2013-12-23 2 views
7

У меня есть Activity в TabHost с 3 другими видами деятельности. Следовательно, они всегда живы (или находятся в состоянии «на паузе»).Утилизация Bitmap не освобождает память

Первое действие имеет четыре разных изображения (~ 250 кбайт каждый), и они извлекают много памяти (около 80 МБ. Просто чтобы указать, я загружаю минимальный размер, необходимый для экрана, и я использую layout_weight, если это помогает), поэтому я хочу свести к минимуму объем требуемой памяти.

Я уже пытался удалить изображения на OnPause состоянии и установить их снова на OnResume, но у меня не было удачи, это один из примеров того, что я пытаюсь сделать:

imageView.Drawable.Callback = null; 
((BitmapDrawable)imageView.Drawable).Bitmap.Recycle(); 
imageView.Drawable.Dispose(); 
imageView.SetImageDrawable(null); 
imageView.SetImageBitmap(null); 
GC.Collect(); 

I не знаю, является ли удаление Bitmap на OnPause - лучшая стратегия, но она должна работать. Я не понимаю, почему ImageView не собирается на GC (так как нет внешних ссылок)

EDIT Это, как я загружаю изображения. Он не работает, даже если я помещаю изображения в xml-файл. Кроме того, мне не нужен этот код, я просто хочу, чтобы располагал растровые изображения.

 void SetBackgroundImages(int imageId, int resId, float width, float height) { 
     var imageView = FindViewById<ImageView>(imageId); 
     using (var bitmap = DecodeSampledBitmapFromResource(Resources, resId, width, height)) 
      imageView.SetImageBitmap(bitmap); 

    } 
    public static Bitmap DecodeSampledBitmapFromResource(Resources res, int resId, float reqWidth, float reqHeight) { 

    var options = new BitmapFactory.Options {InJustDecodeBounds = true}; 
    using (var b = BitmapFactory.DecodeResource(res,resId,options)){} 
     options.InSampleSize = CalculateInSampleSize(options, reqWidth, reqHeight); 
     options.InJustDecodeBounds = false; 
     return BitmapFactory.DecodeResource(res, resId, options); 
    } 
+0

Как именно вы загружаете свои изображения? Просто говоря «ImageView» растянуть или масштабировать изображение, не означает, что вы загружаете его с минимальным размером. Afaik, вам также нужно «Invalidate'' ImageView », чтобы выпустить ссылку на« Bitmap ». – Cheesebaron

+0

Благодарим вас за ответ. Дело не в этом, но я загружаю изображения как точки доступа Xamarin (и Google) (http://docs.xamarin.com/recipes/android/resources/general/load_large_bitmaps_efficiently/), получая образец. Я попытался сделать недействительным ImageView (спасибо), но нет никакой разницы, в OnResume я получаю исключение OutOfMemmory ... – Adam

+0

Какие части вы используете? Укажите код, в котором вы действительно загружаете изображение в представление. – Cheesebaron

ответ

7

В конце вызова java.lang.System.gc() после удаления изображений сделал трюк.

+1

Это фактически 'java.lang.System.gc();' –

1
using (var imageView = FindViewById<ImageView>(Resource.Id.imageView1)) 
    using (var bitmap = Android.Graphics.BitmapFactory.DecodeResource(
      this.Resources, Resource.Drawable.Icon)) 
     imageView.SetImageBitmap(bitmap); 

я видел этот подход в нескольких местах, еще один является использование WeakReference для ImageView. Эти подходы могут помочь GC правильно собрать ссылку на ImageView.

+0

спасибо, это работает для меня! –

Смежные вопросы