2013-05-08 6 views
7

私はAndroidアプリにユニバーサル画像ローダーを統合しようとしています。 GridViewがあり、インターネットから取得した画像が表示されます。 通常の方法でgetView()でイメージをロードするArrayAdapterを使用して実装しました。ユニバーサル画像ローダーキャッシュ

これは、画像を正しく表示するという点でうまく機能します。 しかし、メモリキャッシュからイメージを読み込む際に予期しない動作が発生しました。

  1. アクティビティが開始されると、UILはインターネットまたはディスクキャッシュから画像を読み込みます(存在する場合)。 (もちろん、予期した動作です)
  2. GridViewを画面から最初の列が外れるまでスクロールし、上にスクロールします。 この時点では、メモリキャッシュではなく、ディスクキャッシュから最初の列のイメージがロードされます。
  3. 次に、スクロールして再び上に移動します。 このとき、最初の列の画像はメモリキャッシュからロードされます。

私は上記の操作のステップ2である表示の2回目にメモリキャッシュから画像が読み込まれると予想しています。 この場合、なぜディスクキャッシュが使用されるのかわかりません。

ここは私のコードです。

ImageLoaderConfiguration

ImageLoaderConfiguration mImageLoaderConfig = 
     new ImageLoaderConfiguration.Builder(getApplicationContext()) 
       .defaultDisplayImageOptions(defaultOptions) 
       .enableLogging() 
       .build(); 

DisplayImageOptions ArrayAdapter

DisplayImageOptions defaultOptions = 
     new DisplayImageOptions.Builder() 
       .cacheInMemory() 
       .cacheOnDisc() 
       .showImageForEmptyUri(R.drawable.empty_photo) 
       .showStubImage(R.drawable.empty_photo) 
       .displayer(new FadeInBitmapDisplayer(500)) 
       .build(); 

getViewメソッド()

if (convertView == null) { 
    convertView = (FrameLayout) LayoutInflater.from(getContext()) 
      .inflate(mLayoutId, null); 
    convertView.setLayoutParams(mImageViewLayoutParams); 
} else { // Otherwise re-use the converted view 
    convertView.findViewById(R.id.videoIconInThumbnail).setVisibility(View.GONE); 
} 

// Check the height matches our calculated column width 
if (convertView.getLayoutParams().height != mItemHeight) { 
    convertView.setLayoutParams(mImageViewLayoutParams); 
} 

ImageView image = (ImageView) convertView.findViewById(R.id.photoThumbnail); 
ImageLoader.getInstance().displayImage(thumbnailUrl, image, 
     new SimpleImageLoadingListener() { 

      @Override 
      public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { 
       Log.v(TAG, imageUri + " is loaded."); 
      } 
     }); 
return convertView; 

のGridView

における要素のレイアウトXML

UILのバージョンは1.8.4です。 テスト済みAndroidバージョンは4.1.2です。

上記の操作で画像を3回読み込んだときのUILのログ出力を追加しました。

// Fist time of displaying 
I/ImageLoader(7404): Start display image task [http://xxx/yyy.JPG_1080x1776] 
I/ImageLoader(7404): Load image from disc cache [http://xxx/yyy.JPG_1080x1776] 
I/ImageLoader(7404): Subsample original image (x192) to x192 (scale = 1) [http://xxx/yyy.JPG_1080x1776] 
I/ImageLoader(7404): Cache image in memory [http://xxx/yyy.JPG_1080x1776] 
I/ImageLoader(7404): Display image in ImageView [http://xxx/yyy.JPG_1080x1776] 

// Second time of displaying 
I/ImageLoader(7404): ImageLoader is paused. Waiting... [http://xxx/yyy.JPG_358x357] 
I/ImageLoader(7404): Start display image task [http://xxx/yyy.JPG_358x357] 
I/ImageLoader(7404): Load image from disc cache [http://xxx/yyy.JPG_358x357] 
I/ImageLoader(7404): Subsample original image (x192) to x192 (scale = 1) [http://xxx/yyy.JPG_358x357] 
I/ImageLoader(7404): Cache image in memory [http://xxx/yyy.JPG_358x357] 
I/ImageLoader(7404): Display image in ImageView [http://xxx/yyy.JPG_358x357] 

// Third time of displaying 
I/ImageLoader(7404): Load image from memory cache [http://xxx/yyy.JPG_358x357] 

ありがとうございます。

答えて

10

これはUILのロジックによるものです。

1)初めてImageViewが表示されたため、ImageViewのサイズが不明です。したがって、UILはImageViewのサイズをフルスクリーンサイズとみなし、このサイズのビットマップ(縦横比を考慮して1080x1776)に画像をデコードし、このビットマップをメモリにキャッシュします。

2)描画されたImageViewの実際のサイズは(全画面サイズよりも小さい)既知であり、UIL検索では適切なサイズのビットマップがキャッシュされますが、キャッシュには以前の大きなBitmapしか含まれていません。だからUILは画像を小さなビットマップに再びデコードし、メモリにもキャッシュします。

3)次のディスプレイは、必要なサイズのキャッシュ済みビットマップを使用します。

これは単なるUILの機能です。設定を保存するためにdenyCacheImageMultipleSizesInMemory()を使用することをお勧めします。

+0

あなたの返信ありがとうございます。 私は理解しています。 異なるサイズのイメージ間で同じメモリキャッシュを共有する方法はありません。 そうなら、私は他の解決策を考えます。 ありがとうございます。 – KSJ

+0

"異なるサイズのイメージ間で同じメモリキャッシュを共有する"というものは、どういう意味ですか? – NOSTRA

+0

私は、目標サイズが異なっていても、以前にキャッシュされていたメモリキャッシュからUILがイメージをロードすることを希望します。 – KSJ

0

これを避けるには、イメージをデコードする前にImageViewの幅と高さをUILに知らせることができます。アンドロイド:maxWidth android:maxHeight "ImageViewに

関連する問題