2012-01-26 12 views
1

私は、各アイテムにダウンロードする必要のある画像が含まれている、動的に読み込まれたリストビューを使用するアプリケーションで作業しています。さらに、リスト内の項目をクリックすると、詳細ページが開き、さらにいくつかの画像に加えて同じ画像が表示されます。キャッシュがキャッシュされていないImageDownloaderの使用

私たちが知っているように、非同期タスクを使用して実際のダウンロードを行い、キャッシュメカニズムを使用してイメージの表示を高速化し、複数のダウンロードで実際のデータ使用を最小限に抑えることがベストです。

かなり検索したところ、http://developer.android.com/resources/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.htmlにあるGoogleのサンプルコードを使用すると、画像をダウンロードするための非同期とキャッシュの両方の方法となっています。

私が抱えている問題は、このクラスが呼び出されたときに画像が正しくキャッシュされていないようです。だからここ

私は画像のダウンロードを呼び出して、私のカスタムクラスのコードの一部は(つまり、リストビューを作成します)これです....行く:ImageDownloaderは上記参照されるクラスであることで

ImageDownloader getimage = new ImageDownloader(); 
getimage.download(logoURL, ivLogo); 

イメージが読み込まれますが、毎回ウェブからロードされていることは明らかです。私はImageDownloader.classにいくつかのログを追加して、いつ何が起こっているのかを追跡しました。私が見つけたのは、画像が初めて要求されたときに、(期待通りに)キャッシュから取得する最初の呼び出しに失敗し、getBitmapFromCacheがnullを返し、forceDownloadが呼び出されました。

public void download(String url, ImageView imageView, String cookie) { 
    resetPurgeTimer(); 
    Bitmap bitmap = getBitmapFromCache(url); 
    Log.i(LOG_TAG, "Bitmap is: " + bitmap); 

    if (bitmap == null) { 
     Log.i(LOG_TAG, "Forcing Download"); 
     forceDownload(url, imageView, cookie); 
    } else { 
     cancelPotentialDownload(url, imageView); 
     imageView.setImageBitmap(bitmap); 
    } 
} 

実行が、それは私がキャッシュが追加されたことを確認した後、getBitmapFromCacheを行っ両方にログインする追加のキャッシュ

private void addBitmapToCache(String url, Bitmap bitmap) { 
    Log.i(LOG_TAG, "Incoming Add Cache Info: URL: " + url + " Bitmap: " + bitmap); 
    if (bitmap != null) { 
     Log.i(LOG_TAG, "Entering the add image to cache section"); 
     synchronized (sHardBitmapCache) { 
      sHardBitmapCache.put(url, bitmap); 
      Bitmap returnedbitmap = getBitmapFromCache(url); 
      Log.i(LOG_TAG, "Returned bitmap immediately after adding: " + bitmap); 
     } 
    } 
} 

に画像/ URLを追加してポイントにクラスダウン進むにつれて、ログには返されたビットマップ/ URLハッシュが正しく返されることが示されます。

Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Hard Bitmap is: null 

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Return from initial entry call: null 

Entering forced Download 

Incoming Add Cache Info: URL:http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.pngBitmap: [email protected] 

Entering the add image to cache section 

Trying Hard Cache withURL: http://www.yourlogoresources.com/wpcontent/uploads/2011/11/Wendys-logo.png 

Hard Bitmap is: [email protected] 

Returned bitmap immediately after adding:[email protected] 

は、だから、キャッシュは、しかし、適切にその画像が要求され、次回に移入され表示されます(あなたはリストビューをスクロールするとIE)、キャッシュされた画像は、getBitmapFromCache(URL)からnullを返すと、再び発見されませんエントリポイントのダウンロード

Incoming request to get Image, URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Trying Hard Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Hard Bitmap is: null 

Trying Soft Cache with URL: http://www.yourlogoresources.com/wp-content/uploads/2011/11/Wendys-logo.png 

Return from initial entry call: null 

Entering forced Download 

だから私はキャッシュが移入され表示されますが、それが再度チェックされたときに、ヌルが、何も返されなかった理由として、ここで途方に暮れています。

myActivity.GetImage.download(logoURL, ivLogo); 

public class myActivity extends Activity implements OnClickListener { 
    public final static ImageDownloader GetImage = new ImageDownloader(); 

は次に、このどこかのように私はImageDownloadが必要であると呼ばれる:私は次のように私のメインのActivityからImageDownloaderへの静的参照を使用して終了

EDIT

ありがとうございました。

答えて

1

ImageDownloaderのコードを見てください。それは、一次キャッシュ private final HashMap<String, Bitmap> sHardBitmapCache

private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache

エントリは次キャッシュから追い出さ二静的キャッシュを使用している

二次キャッシュに入れています。

ImageDownloaderの新しいインスタンスを作成すると、毎回ImageDownloaderのインスタンスにこのインスタンスを使用してダウンロードした1つのイメージしか存在しないため、実質的にキャッシュメカニズムが使用されません。

PS:問題のコードは、ダウンロードごとにインスタンスを使用しているようです。

+0

Vikram、はい私はあなたが正しいと信じて、私はすべてのイメージの新しいインスタンスを立てます。私は、単一のImageDownloaderインスタンスを立ち上げ、ダウンロードごとにその単一のインスタンスを単に使用する方法を見つけなければならないと思いますか? – brad

+0

そして明らかにするために、私はCustomAdapterクラス(配列を入力として)を最初に呼び出すActivityクラスを持っています。このクラスは配列の各エントリのImageDownloaderクラスを呼び出します。 Javaにはまったく新しいものですが、ImageDownloaderのインスタンスを1つだけインスタンス化する方法についてはわかりませんが、他の複数のクラスからアクセスできます。任意のポインタが評価されるだろう。 – brad

+0

ImageDownloaderのインスタンスをApplicationオブジェクト経由で公開することができます。ここに例があります:http://stackoverflow.com/questions/708012/android-how-to-declare-global-variables。または単に静的オブジェクトにすることができます –