2013-03-17 10 views
7
final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 
    final int cacheSize = maxMemory/8; 
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
      @Override 
      protected int sizeOf(String key, Bitmap bitmap) { 
       // The cache size will be measured in kilobytes rather than 
       // number of items. 
       return bitmap.getByteCount()/1024; 
      } 
     }; 
    URL url = new URL("http://s2.goodfon.ru/image/260463-1920x1200.jpg"); 
    Bitmap bitmap = BitmapFactory.decodeStream((InputStream) url.getContent(), null, options); 
    if(bitmap != null) 
     Log.i("Success", "BITMAP IS NOT NULL"); 

    String key = "myKey"; 
    Log.i("Get is null", "putting myKey"); 
    mMemoryCache.put(key, bitmap); 

    Bitmap newBitmap = mMemoryCache.get(key); 
    if(newBitmap == null) 
     Log.i("newBitmap", "is null"); 

こんにちは、ここにコードがあります。私はURLからビットマップを正常に取得します(ログはビットマップがヌルではなく、簡単に表示できます)。それから私はそれをLruCacheに入れてそれを元に戻そうとしていますが、それはnullを返します。 (ログによると、newBitmapはnullです)。私のミスはどこですか?教えてください。 Android 4.1.2キャッシュサイズ8192 Kb。LruCacheが機能しない

+0

キャッシュサイズの計算が正しいことを試してみましたか? 'sizeOf()'は何を出力しますか?イメージが本当にキャッシュの内側にあるのは確かですか? – ConcurrentHashMap

+0

http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html – Raghunandan

+0

ああ、その画像は9000 kbで、私はファイルとして1.19 MBと思っていました。問題が解決しました。ありがとうございました。なぜ、1.19 MBのファイルがgetByteCount/1024で9000 kbを返すのですか? – Faceles

答えて

8

ディスクで1.19MB、メモリが9MBの場合は、圧縮されたJPEGファイルとして1.19MBということを意味し、それをビットマップ(圧縮されていない)に抽出して表示できると、 9 MBのメモリ。コードスニペットのURLで示唆されているように1920 x 1200ピクセルの画像の場合、画像は1920 x 1200 x 4バイトのメモリを使用します(ARGB値を0から256までの各ピクセルで4バイト、合計230万= 9,216,000バイト)。このキャッシュに使用可能なメモリの1/8を使用している場合は、9MBがその合計メモリ容量を超えている可能性があります。そのため、ビットマップはキャッシュに格納されないか、すぐに削除されます。

デコード時に画像をダウンサンプリングする必要があるかもしれません。もしそれが大きい場合は(BitmapFactory.Options.inSampleSizeを使用してください。

また、Runtime.maxMemoryを使用してキャッシュサイズを計算しています。これは、VM全体が使用できる最大量のメモリを要求していることを意味します。

http://developer.android.com/reference/java/lang/Runtime.html#maxMemory%28%29

より一般的なアプローチは、使用ActivityManager.getMemoryClass()メソッドによってあなたに戻って与えられた値です。

ここでは、参考のためにコードスニペットとメソッド定義の例を示します。

ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
    int memClassBytes = am.getMemoryClass() * 1024 * 1024; 
    int cacheSize = memClassBytes/8; 
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) 

http://developer.android.com/reference/android/app/ActivityManager.html#getMemoryClass%28%29

+0

もし私がフットボールの解説者だったならば、リッチストライクスは再びゴール、ダルビックはこのコードを止める機会はありません。 –

0

また、次の行に1024ランタイムmaxMemoryを分割する際のAndroid例が間違っていたlrucache

final Bitmap bmp = mLruCache.put(key, data); 
if (bmp != null) 
    bmp.recycle(); 
0

から飛び出すビットマップを再利用することができます。

final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 

maxMemoryの単位はByteで、 'c acheSize '('/8 'は、現在のアクティビティで使用可能なメモリの8分の1を使用することを意味します)。したがって、 '/ 1024'は 'mMemoryCache'にビットマップを実際にキャッシュすることができないように 'cacheSize'を極端に小さくします。

解決策は上記のコードでは '/ 1024'が削除されます。

関連する問題