通用图像加载器:忽略 ImageScaleType
Universal Image Loader: ImageScaleType is ignored
我正在使用 UIL 加载位图。它工作正常。但是我在将它与小部件一起使用时遇到了问题。
我正在加载自定义 NonViewAware
:
private static class WidgetImageAware extends NonViewAware
{
protected final int mId;
public WidgetImageAware(int imageSize, int id)
{
super(new ImageSize(imageSize, imageSize), ViewScaleType.CROP);
mId = id;
}
@Override
public int getId()
{
return mId;
}
}
要设置缩放比例,我在 DisplayImageOptions
中使用 imageScaleType(ImageScaleType.EXACTLY)
。
调用后:
imageLoader.displayImage(someUri, new WidgetImageAware(480, id), displayImageOptions, new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
height = loadedImage.getHeight() // height == 950 !!
width = loadedImage.getWidth() // width == 950 !!
}
});
因此加载的位图大小 (950x950) 比 Aware 中请求的 (480x480) 大得多。我需要加载大小正好为 480x480 的位图。否则小部件的更新将抛出:
java.lang.IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage (used: 3632836, max: 2304000) The total memory cannot exceed that required to fill the device's screen once.
因此在使用具有两个不同 ImageScaleType 的 DisplayImageOptions 的两个实例时出现错误。
它根据首先使用的 ImageScaleType 进行缓存,所有正在进行的 ImageScaleTypes 都将被忽略。这是由忽略 ImageScaleType 的缓存中的密钥生成过程引起的。
我已将问题简化为以下测试示例:
public void testMultipleImageScaleTypes() throws InterruptedException
{
final CountDownLatch lock = new CountDownLatch(1);
final List<Bitmap> bitmaps = new ArrayList<>();
// this image is 950x950
final String uri = "http://spaceplace.nasa.gov/review/3d-gallery/sun-sdo-disk.en.jpg";
final DisplayImageOptions first = new DisplayImageOptions.Builder().imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2).cacheInMemory(true).build();
final DisplayImageOptions second = new DisplayImageOptions.Builder().imageScaleType(ImageScaleType.EXACTLY).cacheInMemory(true).build();
ImageLoader.getInstance().init(new ImageLoaderConfiguration.Builder(getContext()).memoryCache(new LRULimitedMemoryCache(2048)).build());
ImageLoader.getInstance().displayImage(uri, new NonViewAware(new ImageSize(480,480), ViewScaleType.CROP), first, new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
bitmaps.add(loadedImage);
ImageLoader.getInstance().displayImage(uri, new NonViewAware(new ImageSize(480,480), ViewScaleType.CROP), second, new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
bitmaps.add(loadedImage);
lock.countDown();
}
});
}
});
lock.await(1, TimeUnit.HOURS);
assertEquals(950, bitmaps.get(0).getWidth());
assertEquals(950, bitmaps.get(0).getHeight());
assertEquals(480, bitmaps.get(1).getWidth()); // it fails here - bitmap size is 950x950
assertEquals(480, bitmaps.get(1).getHeight());
}
我已提交错误报告。解决方法可能是对不同的 ImageScaleType 使用不同的 ImageLoader 实例。但是很浪费内存。
我正在使用 UIL 加载位图。它工作正常。但是我在将它与小部件一起使用时遇到了问题。
我正在加载自定义 NonViewAware
:
private static class WidgetImageAware extends NonViewAware
{
protected final int mId;
public WidgetImageAware(int imageSize, int id)
{
super(new ImageSize(imageSize, imageSize), ViewScaleType.CROP);
mId = id;
}
@Override
public int getId()
{
return mId;
}
}
要设置缩放比例,我在 DisplayImageOptions
中使用 imageScaleType(ImageScaleType.EXACTLY)
。
调用后:
imageLoader.displayImage(someUri, new WidgetImageAware(480, id), displayImageOptions, new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
height = loadedImage.getHeight() // height == 950 !!
width = loadedImage.getWidth() // width == 950 !!
}
});
因此加载的位图大小 (950x950) 比 Aware 中请求的 (480x480) 大得多。我需要加载大小正好为 480x480 的位图。否则小部件的更新将抛出:
java.lang.IllegalArgumentException: RemoteViews for widget update exceeds maximum bitmap memory usage (used: 3632836, max: 2304000) The total memory cannot exceed that required to fill the device's screen once.
因此在使用具有两个不同 ImageScaleType 的 DisplayImageOptions 的两个实例时出现错误。
它根据首先使用的 ImageScaleType 进行缓存,所有正在进行的 ImageScaleTypes 都将被忽略。这是由忽略 ImageScaleType 的缓存中的密钥生成过程引起的。
我已将问题简化为以下测试示例:
public void testMultipleImageScaleTypes() throws InterruptedException
{
final CountDownLatch lock = new CountDownLatch(1);
final List<Bitmap> bitmaps = new ArrayList<>();
// this image is 950x950
final String uri = "http://spaceplace.nasa.gov/review/3d-gallery/sun-sdo-disk.en.jpg";
final DisplayImageOptions first = new DisplayImageOptions.Builder().imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2).cacheInMemory(true).build();
final DisplayImageOptions second = new DisplayImageOptions.Builder().imageScaleType(ImageScaleType.EXACTLY).cacheInMemory(true).build();
ImageLoader.getInstance().init(new ImageLoaderConfiguration.Builder(getContext()).memoryCache(new LRULimitedMemoryCache(2048)).build());
ImageLoader.getInstance().displayImage(uri, new NonViewAware(new ImageSize(480,480), ViewScaleType.CROP), first, new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
bitmaps.add(loadedImage);
ImageLoader.getInstance().displayImage(uri, new NonViewAware(new ImageSize(480,480), ViewScaleType.CROP), second, new SimpleImageLoadingListener()
{
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
{
bitmaps.add(loadedImage);
lock.countDown();
}
});
}
});
lock.await(1, TimeUnit.HOURS);
assertEquals(950, bitmaps.get(0).getWidth());
assertEquals(950, bitmaps.get(0).getHeight());
assertEquals(480, bitmaps.get(1).getWidth()); // it fails here - bitmap size is 950x950
assertEquals(480, bitmaps.get(1).getHeight());
}
我已提交错误报告。解决方法可能是对不同的 ImageScaleType 使用不同的 ImageLoader 实例。但是很浪费内存。