2015-09-23 20 views
2

我使用UIL加载位图。它工作正常。但在使用小部件时遇到问题。通用图像加载器:ImageScaleType被忽略

我与定制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 !! 
     } 
    }); 

所以加载的位图的大小比在感知(小480x480)要求更大(950x950)。我需要加载大小正确为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. 
+0

也许这个答案可以帮助你 - http://stackoverflow.com/a/15744035/2308720 – Oleksandr

+0

不幸的是没有。所有尺寸均按要求设置:getWidth和getHeight返回480,ImageScaleType设置为EXACTLY。 – Bhiefer

回答

0

所以有使用两个不同的ImageScaleTypes DisplayImageOptions的两种情况下,是一个错误。

它根据首次使用的ImageScaleType进行缓存,所有正在进行的ImageScaleType都被忽略。这是由忽略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()); 
} 

我已经提交bug报告。解决方法可能是针对不同的ImageScaleType使用不同的ImageLoader实例。但这是相当浪费的记忆。