2012-02-16 87 views
7

我有一块图像要加载到我的屏幕上。所有图像都是我下载并存储在SD-CARD上的文件。安卓快速位图加载

到目前为止,我发现了两种方式来做到这一点,首先是加载它们在主线程,当活动开始,(我有大约70图像和我花约2.1秒加载它们全部)。

另一种方式是我现在正在测试的东西。将它们加载到分离的线程上,同时我可以向用户显示加载动画。现在我的执行ThreadPoolExecutor花了4.3秒。我在10个线程上完成了它。

而最后的方法,(那就是我还不测试的唯一的事)正在与精灵表。

我不能使用应用程序缓存,因为在我的应用程序中,我有很多屏幕,每个屏幕都有自己的图像集。

你怎么想,什么是加载大量图像的最快方法?你知道什么加速工艺,可以帮助我吗?

+0

你还没有提到你的图像的大小,如果你能减少它们的大小,当你加载它们(如取一个500万像素的JPEG并将其作为320x240缩略图加载)。如果你允许这样做,它可以大大加速图像的加载。 – BitBank 2012-02-25 00:05:50

回答

2

一种选择是使用使用WeakReference创建图像缓存,以便系统遇到内存不足情况时将图像从内存中移除。这样,您可以将图像保存在内存中,并且只需在SD卡不在内存中时加载即可。所以你当前的活动将始终保持对所需位图的硬引用,并且图像缓存将保留对位图的弱引用。

以下是关于弱引用一些信息:

JavaDoc weakReference

StackOverflow post discussing using weak reference for cache

+1

-1:这种方法在所有sdk9以上的设备上没有任何用处,因为垃圾回收器非常具有侵略性,它几乎可以清除所有弱引用,当前推荐的方法是LRU Cache(请参阅http://developer.android.com/training /displaying-bitmaps/cache-bitmap.html) – for3st 2014-04-08 10:51:14

8
  1. 请勿在主线程中加载。如果您阻止主线程,延迟2.1秒会导致ANR(应用程序无响应)错误导致死亡。

  2. 加载在单独的线程中。不要创建10个线程,而是创建一个AsyncTask,并在doInBackground中逐个加载所有图像。

    在AsyncTask中加载应该(几乎)与在主线程中加载相同的时间。不要放太多花哨的动画,这样主线程不会消耗太多的CPU时间。

0

这样做的一种方法是实现一种监听器/观察者。

从你的UI线程,启动其他线程,将加载图像。一旦图像被加载,线程将调用activity类中实现的回调方法来更新相应的图像视图。

而不是android异步任务,我会去我的线程(池/执行程序)。我将在加载它们之前获取所有可能的图像路径,并将它们分派给线程加载图像。在回调中,我知道在哪里更新图像。

另外,你也可以检查加载程序如何执行你的情况。

0

显然,你不应该在UI线程中留下2s长的操作。

我假设的ThreadPoolExecutor是二年即可回收解决方案,但它不是最佳的在池中创建多个线程。在后台线程就足够了。我敢打赌,只要改变这一点,你的表现就会更好。

我不直接从活动推荐的AsyncTask,因为it is fragile to config change

我不建议使用精灵。在内存有限的移动设备上增加一张图像的尺寸是非常危险的。特别是精灵,你必须得到部分Bitmap,因此在内存中有完整的位图一会儿。

现在我明白了您的具体问题,我想你会通过Lazy loading of images in a listview,因为问题非常相似。