我正在尝试将Universal Image Loader集成到我的Android App中。 它有一个GridView,显示从互联网上获取的图像。 我使用ArrayAdapter实现它,它以通常的方式在getView()中加载图像。
在正确显示图片方面效果很好。 但是我在从内存缓存加载图像时发现了一个意外的行为。
我希望在第二次显示时从内存缓存加载图像,这是上面的操作中的第2步。 我不知道为什么在这种情况下会使用光盘缓存。
这是我的代码。
ImageLoaderConfiguration
ImageLoaderConfiguration mImageLoaderConfig =
new ImageLoaderConfiguration.Builder(getApplicationContext())
.defaultDisplayImageOptions(defaultOptions)
.enableLogging()
.build();
DisplayImageOptions
DisplayImageOptions defaultOptions =
new DisplayImageOptions.Builder()
.cacheInMemory()
.cacheOnDisc()
.showImageForEmptyUri(R.drawable.empty_photo)
.showStubImage(R.drawable.empty_photo)
.displayer(new FadeInBitmapDisplayer(500))
.build();
ArrayAdapter中的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
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/photoThumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" >
</ImageView>
<ImageView
android:id="@+id/videoIconInThumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_play"
android:visibility="gone" >
</ImageView>
</FrameLayout>
UIL的版本是1.8.4。 经测试的Android版本为4.1.2。
使用上述操作将图像加载三次时,添加了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]
谢谢。
答案 0 :(得分:10)
这是因为UIL的逻辑。
1)第一次(ImageLoader.displayImage(...)
)ImageView的大小未知,因为它尚未在屏幕上绘制。因此,UIL将ImageView的大小视为全屏大小,将图像解码为此大小的位图(1080x1776,考虑宽高比)并将此位图缓存在内存中。
2)第二次绘制的ImageView的实际大小是已知的(小于全屏大小),UIL搜索缓存了适当大小的Bitmap,但缓存只包含以前的大型Bitmap,这对我们的需求来说太大了。因此,UIL将图像再次解码为较小的Bitmap,并将其缓存在内存中。
3)以下显示使用已缓存的所需大小的位图。
所以这只是UIL的一个功能。我建议您在配置中使用denyCacheImageMultipleSizesInMemory()
来节省内存。
答案 1 :(得分:0)