2013-05-22 9 views
34

新しいVolleyライブラリを使用してイメージキャッシュを実装する際に問題があります。プレゼンテーションでは、コードがBitmapLruCacheは明らかにツールキットには含まれていません。このAndroid Volley ImageLoader - BitmapLruCacheパラメータ?

mRequestQueue = Volley.newRequestQueue(context); 
mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache()); 

のように見えます。どのようにそれを実装するか、いくつかのリソースに私を指す任意のアイデア?

http://www.youtube.com/watch?v=yhv8l9F44qo 14 @:38回の

ありがとう!

答えて

48
import android.graphics.Bitmap; 
import android.support.v4.util.LruCache; 

public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageCache { 
    public static int getDefaultLruCacheSize() { 
     final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024); 
     final int cacheSize = maxMemory/8; 

     return cacheSize; 
    } 

    public BitmapLruCache() { 
     this(getDefaultLruCacheSize()); 
    } 

    public BitmapLruCache(int sizeInKiloBytes) { 
     super(sizeInKiloBytes); 
    } 

    @Override 
    protected int sizeOf(String key, Bitmap value) { 
     return value.getRowBytes() * value.getHeight()/1024; 
    } 

    @Override 
    public Bitmap getBitmap(String url) { 
     return get(url); 
    } 

    @Override 
    public void putBitmap(String url, Bitmap bitmap) { 
     put(url, bitmap); 
    } 
} 
+0

おかげで多くのことを処理する新しいAPIで提供されます、ところで、どのようにあなたのキャッシュの適切なサイズを決定するのですか?彼はスクリーンサイズの関数が論理的だと話していますが、もっと正確にするにはどうすればいいですか? – urSus

+0

@Vlasto Benny Lava、わかりませんが、 'N * screen_width * screen_height'と' N〜10'のようなものが論理的に見えます。 –

+0

何が起きるかはうまくいきますが、画面が消えて戻ってくるとイメージが再び読み込まれるので、メモリキャッシュから追い出されたと思いますか?それが何であるか、どんな考えですか? – urSus

1

私はこのキャッシュは、あなたのアプリケーションのすべての生命の間に利用可能であることを行っているので、シングルトンのビットマップキャッシュを使用しているお勧めします。

public class BitmapCache implements ImageCache { 
    private LruCache<String, Bitmap> mMemoryCache; 

    private static BitmapCache mInstance; 

    private BitmapCache(Context ctx) { 
     final int memClass = ((ActivityManager) ctx 
       .getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); 
     // Use 1/16th of the available memory for this memory cache. 
     final int cacheSize = 1024 * 1024 * memClass/16; 
     mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { 
      @Override 
      protected int sizeOf(String key, Bitmap value) { 
       return value.getRowBytes() * value.getHeight(); 
      } 
     }; 
    } 

    public static BitmapCache getInstance(Context ctx) { 
     if (mInstance == null) { 
      mInstance = new BitmapCache(ctx); 
     } 
     return mInstance; 
    } 

    @Override 
    public Bitmap getBitmap(String url) { 
     return mMemoryCache.get(url); 
    } 

    @Override 
    public void putBitmap(String url, Bitmap bitmap) { 
     mMemoryCache.put(url, bitmap); 
    } 
} 
5

はボレーとディスクベースLRUキャッシュを用いた例です。 Jake Whartonによって管理されているAOSPのDiskLruCacheのバージョンを使用しています。 http://blogs.captechconsulting.com/blog/raymond-robinson/google-io-2013-volley-image-cache-tutorial

編集:私はこの方法が推奨される方法であるため、インメモリーLRUキャッシュをデフォルトの実装として組み込むようにプロジェクトを更新しました。 Volleyは、独自のL2キャッシュでディスクベースのキャッシュを暗黙的に処理します。イメージキャッシュはL1キャッシュに過ぎません。私はオリジナルの投稿を更新し、ここにいくつかの詳細を追加しました:http://www.thekeyconsultant.com/2013/06/update-volley-image-cache.html

+1

あなたのライブラリでは、ディスクキャッシュに必要な鍵を生成するためにurl.hashCode()を使用しているようです。それは本当に安全ですか? hashCodesはユニークではないので、ランダムに同じハッシュコードに解決されるURLのキャッシュヒットが不正になることはありませんか?私は他の人がMD5を使用して衝突の危険を減らすのを見てきました。いくつかはAndroids非スレッドセーフのMessageDigestクラスを避けるために独自のMD5実装を提供しています。この(潜在的な)問題に関する提案はありますか? –

+1

あなたは正しいです、これはデモのための場所に置かれ、大部分の時間を費やしています。私は実行可能な代替手段としてUUID.fromString()の速度をテストしています。 – rdrobinson3

0

このさがOOMに

public class BitmapMemCache extends LruCache<string, Bitmap> implements ImageCache { 

    public BitmapMemCache() { 
     this((int) (Runtime.getRuntime().maxMemory()/1024)/8); 
    } 

    public BitmapMemCache(int sizeInKiloBytes) { 
     super(sizeInKiloBytes); 
    } 

    @Override 
    protected int sizeOf(String key, Bitmap bitmap) { 
     int size = bitmap.getByteCount()/1024; 
     return size; 
    } 

    public boolean contains(String key) { 
     return get(key) != null; 
    } 

    public Bitmap getBitmap(String key) { 
     Bitmap bitmap = get(key); 
     return bitmap; 
    } 

    public void putBitmap(String url, Bitmap bitmap) { 
     put(url, bitmap); 
    } 
} 
関連する問題