在android中的后台线程中从磁盘加载缓存的图像

时间:2013-04-08 10:12:14

标签: android multithreading caching

我有一个列表视图,其中图像从Internet加载,然后缓存在磁盘上。在滚动时,我尝试使用ExecutorService在后台线程中从磁盘加载图像(因为在滚动时会有多个图像) - 类似这样的事情:

executorService.submit(new Runnable() {
    @Override
    public void run() {
           // load images from the disk
           // reconnect with UI thread using handler
        }
}

然而,滚动并不是很平滑且非常生涩 - 好像UI线程在某处被阻塞了。但是当我评论这个给定的代码时,滚动是顺利的。我无法理解我的实施中的缺陷。

编辑:刚才我发现当我从后台线程将消息传递给UI线程时,问题就出现了。如果我评论该部分,则滚动是平滑的(但是当然没有显示图像)

1 个答案:

答案 0 :(得分:1)

您可以使用延迟加载或通用图像加载器

Lazy List是使用url从sdcard或fomr服务器延迟加载图像。这就像点播加载图片一样。

图像可以缓存到本地SD卡或手机存储卡中。网址被认为是关键。如果密钥存在于sdcard显示图像来自SD卡,则通过从服务器下载显示图像并将其缓存到您选择的位置。可以设置缓存限制。您还可以选择自己的位置来缓存图像。缓存也可以被清除。

而不是用户等待下载大图像,然后显示延迟列表按需加载图像。由于缓存了图像区域,您可以离线显示图像。

https://github.com/thest1/LazyList。懒惰列表

在你的getview中

imageLoader.DisplayImage(imageurl, imageview); ImageLoader Display method

public void DisplayImage(String url, ImageView imageView) //url and imageview as parameters
{
imageViews.put(imageView, url);
Bitmap bitmap=memoryCache.get(url);   //get image from cache using url as key
if(bitmap!=null)         //if image exists
imageView.setImageBitmap(bitmap);  //dispaly iamge
else   //downlaod image and dispaly. add to cache.
{
queuePhoto(url, imageView);
imageView.setImageResource(stub_id);
}
}

Lazy List的替代方案是Universal Image Loader

https://github.com/nostra13/Android-Universal-Image-Loader

它基于Lazy List(基于相同的原理)。但它有很多其他配置。我更喜欢使用Universal Image Loader,它为您提供了更多配置选项。如果下载失败,您可以显示错误图像。可以显示带圆角的图像。可以缓存在光盘或内存上。可压缩图像。

在自定义适配器构造函数

 File cacheDir = StorageUtils.getOwnCacheDirectory(a, "your folder");

// Get singletone instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
  // You can pass your own memory cache implementation
 .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
 .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
 .enableLogging()
 .build();
 // Initialize ImageLoader with created configuration. Do it once.
 imageLoader.init(config);
 options = new DisplayImageOptions.Builder()
 .showStubImage(R.drawable.stub_id)//display stub image
 .cacheInMemory()
 .cacheOnDisc()
 .displayer(new RoundedBitmapDisplayer(20))
 .build();

在你的getView()

ImageView image=(ImageView)vi.findViewById(R.id.imageview); 
imageLoader.displayImage(imageurl, image,options);//provide imageurl, imageview and options

您可以配置其他选项以满足您的需求。

除了延迟加载/通用图像加载器,您还可以查看持有者以获得平滑滚动和性能

http://developer.android.com/training/improving-layouts/smooth-scrolling.html