多くの画像を表示するカスタム ビュー (グリッド ビューに似ています) を作成したので、このアプリケーションではビットマップのリサイクルが必要です。ビットマップのリサイクルを処理するために、Lru キャッシュ (以下に実装) を使用しています。これを Android 2.3 デバイスでテストした (そして高速でスクロールした) と、次のエラー メッセージが表示され、アプリがクラッシュしました。バグを再現する方法を見つけた後、Android 4.0 でテストしたところ、問題なく動作しました。
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 android.graphics.Bitmap@407fc6b8
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
このバグを追跡したところ、ビットマップを ImageView に設定する前に、ビットマップがリサイクルされているかどうかを確認することがわかりました。ただし、ビットマップはそのステップと draw() ステップの間でリサイクルされ、エラーが発生します。
ここに私のキャッシュがあります:
sLruCache = new LinkedHashMap(容量 / 2, 0.75f, true) { private static final long serialVersionUID = -7282875042976381535L; @オーバーライド protected boolean removeEldestEntry(LinkedHashMap.Entry eldest) { if (size() > mCapacity) { true を返します。 } そうしないと false を返します。 } public Bitmap remove(オブジェクトキー) { ビットマップ ビットマップ = super.remove(key); if (ビットマップ != NULL_BITMAP) { ビットマップ.リサイクル(); } ビットマップを返します。 }; @オーバーライド public void clear() { キーを設定 = new HashSet(keySet()); for (文字列キー: キー) { ビットマップ マップ = get(キー); if (マップ != NULL_BITMAP) { map.recycle(); } } super.clear(); } };
これが4.0ではなくAndroid 2.3で失敗する理由についてのアイデアはありますか?