2013-06-27 3 views
1

Я построил пользовательский вид (похожий на вид сетки), который отображает много многих изображений, поэтому переработка растровых изображений является необходимостью для этого приложения. Я использую кэш Lru (реализованный ниже) для обработки утилиты Bitmap. Когда я тестировал это на устройстве Android 2.3 (и быстро прокручивался), я получил следующее сообщение об ошибке, и приложение разбилось. После выяснения того, как копировать ошибку, я протестировал ее на Android 4.0, и все получилось просто отлично.Canvas: пытается использовать переработанное растровое изображение RuntimeException на Android 2.3

06-27 10:57:48.420: E/AndroidRuntime(14255): FATAL EXCEPTION: main 
06-27 10:57:48.420: E/AndroidRuntime(14255): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap [email protected] 
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.graphics.Canvas.throwIfRecycled(Canvas.java:955) 
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.graphics.Canvas.drawBitmap(Canvas.java:1044) 
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325) 
06-27 10:57:48.420: E/AndroidRuntime(14255): at android.widget.ImageView.onDraw(ImageView.java:872) 
etc etc 

Я отслеживал эту ошибку вокруг и получается, что я могу проверить, если Bitmap возвращают перед установкой растрового изображения на ImageView. Однако Bitmap получает рециркуляцию между этим шагом и шагом draw(), вызывая ошибку.

Вот мой кэш:

 sLruCache = new LinkedHashMap(capacity/2, 0.75f, true) { 
     private static final long serialVersionUID = -7282875042976381535L; 

     @Override 
     protected boolean removeEldestEntry(LinkedHashMap.Entry eldest) { 
     if (size() > mCapacity) { 
      return true; 
     } else 
      return false; 
     } 

     public Bitmap remove(Object key) { 
     Bitmap bitmap = super.remove(key); 
     if (bitmap != NULL_BITMAP) { 
      bitmap.recycle(); 
     } 
     return bitmap; 
     }; 

     @Override 
     public void clear() { 
     Set keys = new HashSet(keySet()); 
     for (String key : keys) { 
      Bitmap map = get(key); 
      if (map != NULL_BITMAP) { 
      map.recycle(); 
      } 
     } 
     super.clear(); 
     } 
    }; 

Любые идеи о том, почему это будет терпеть неудачу на Android 2.3, а не 4.0?

+0

'bitmap.recycle()' вы используете переработанное растровое изображение. – Raghunandan

+0

это только тогда, когда он удаляется из кеша. Я считаю, что bitmap.recycle() следует использовать в методе удаления. Кроме того, почему это будет работать на Android 4.0? – rakoonise

+0

http://developer.android.com/training/displaying-bitmaps/manage-memory.html. он будет работать на 4.0 coz, происходит изменение способа выделения памяти для растровых изображений в android 3.0 и выше – Raghunandan

ответ

0

У меня такая же проблема.

И мне пришлось удалить все вызовы Bitmap.recycle(). Иногда это вызывало исключение OutOfMemoryException.

Таким образом, я делаю хак так:

// when I need to remove bitmap from cache 
if (Build.VERSION.SDK_INT < 9 || Build.VERSION.SDK_INT > 10) { 
    bmp.recycle(); 
} 

Это не является хорошим решением, но это может быть полезным.