3

Android BitmapFun サンプル コードを使用して、アプリケーションでビットマップを管理しています。ViewPager で画像が文字化けしたり、重複したりすることがあります。これを ImageCache.java の次のコードまで追跡しました。

           /**
             * Notify the removed entry that is no longer being cached
             */
            @Override
            protected void entryRemoved(boolean evicted, String key,
                    BitmapDrawable oldValue, BitmapDrawable newValue) {
                if (RecyclingBitmapDrawable.class.isInstance(oldValue)) {
                    // The removed entry is a recycling drawable, so notify it 
                    // that it has been removed from the memory cache
                    ((RecyclingBitmapDrawable) oldValue).setIsCached(false);
                } else {
                    // The removed entry is a standard BitmapDrawable

                    if (Utils.hasHoneycomb()) {
                        // We're running on Honeycomb or later, so add the bitmap
                        // to a SoftRefrence set for possible use with inBitmap later
                        mReusableBitmaps.add(new SoftReference<Bitmap>(oldValue.getBitmap()));
                    }
                }
            }

ビットマップは、キャッシュから削除されると、再利用可能なビットマップ リストに追加されます。この場合、ビットマップはまだ ViewPager ビューで使用されています。後でビューが作成されると、ビットマップ (まだ使用中) が再利用され、ビットマップは ViewPager の 2 つの位置に表示されます。

LruCache から削除されたビットマップは、再利用できるとは限りません。このコードでのビットマップの再利用を無効にしたので、問題はなくなりました。ViewPager のオフスクリーン制限の範囲内ではビットマップがキャッシュから削除されないため、この問題は解像度の低い画像では発生しません。60 DPI の画像では問題はありませんが、この問題は 160 DPI で頻繁に見られます。これは、元の BitmapFun サンプルの解像度の高い画像に表示されると思います。

他の誰かがこの問題を経験しましたか、それとも私は問題を正しく理解していませんか?

ケビン

4

1 に答える 1

1

コードの問題は行にあると思います

mReusableBitmaps.add(new SoftReference<Bitmap>(oldValue.getBitmap()));

その行は、LRU キャッシュから削除されたビットマップを、inBitmap の再利用に使用される再利用可能なビットマップ セットに追加します。ImageView によってまだ使用されているかどうかはチェックされません。ImageView でまだ使用されているビットマップを再利用しようとすると、基になるビットマップが別のビットマップに置き換えられ、無効になります。私の提案は、再利用可能なビットマップ セットにビットマップを追加する前に、ビットマップが ImageView によってまだ使用されているかどうかを追跡することです。この問題のサンプル githubプロジェクトを作成しました。私の解決策についてどう思うか教えてください。

于 2013-12-01T04:10:25.847 に答える