Android快速位图加载

7
我有一组图片要加载到屏幕上。所有的图片都是我下载并存储在SD-CARD上的文件。
到目前为止,我发现了两种方法,第一种是在主线程上加载它们,当活动开始时(我大约有70张图片,需要大约2.1秒才能全部加载完)。
另一种方法是我正在测试的方法。在分离的线程上加载它们,同时可以为用户显示加载动画。目前我的ThreadPoolExecutor实现花费了4.3秒。我使用了10个线程。
最后一种方法是使用精灵表。这是唯一我还没有尝试过的方法。
我不能使用应用程序缓存,因为在我的应用程序中,我有很多屏幕,每个屏幕都有自己的图像集。
你认为什么是加载大量图像最快的方法?你知道哪些加速技术可以帮助我提升速度吗?

你没有提到你的图片尺寸,以及是否可以在加载时缩小它们的尺寸(例如将一个5百万像素的JPEG图像作为320x240的缩略图加载)。如果允许这样做,它可以大大加快图像的加载速度。 - BitBank
4个回答

9
  1. 不要在主线程中加载。如果你阻塞了主线程,在 2.1 秒内你就有可能接近 ANR(应用程序无响应)错误而被杀死。

  2. 在单独的线程中加载。不要创建 10 个线程,只需一个 AsyncTask,并在 doInBackground 中一个接一个地加载所有图像。

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


2
一种选择是使用WeakReference创建图像缓存,这样当系统遇到低内存情况时,图像将从内存中删除。这样你可以将图像保留在内存中,并且只需要在它们不在内存中时从sdcard加载。因此,您当前的活动始终会保留对所需位图的硬引用,而图像缓存将保留对位图的弱引用。
以下是有关弱引用的更多信息:
JavaDoc weakReference: JavaDoc 弱引用 StackOverflow帖子讨论使用弱引用进行缓存:StackOverflow 帖子

1
-1:这种方法在所有设备的SDK 9及以上版本上实际上都是无用的,因为垃圾收集器非常积极,几乎立即清除所有弱引用。当前推荐的方法是LRU缓存(请参见http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html)。 - Patrick

0

实现一种监听器/观察者的方法是启动另一个线程来加载图像。当图像加载完成后,线程将调用在活动类中实现的回调方法来更新相应的图像视图。

与Android异步任务不同,我会选择使用自己的线程(池化/执行器)。在加载图像之前,我会获取所有可能的图像路径,并将它们分派到负责加载图像的线程中。在回调中,我知道在哪里更新图像。

或者您也可以检查Loader在您的情况下的表现如何。


0

显然,你不应该在UI线程中留下一个持续2秒的操作。

我想ThreadPoolExecutor是一个好的解决方案,但在池中创建许多线程并不是最优的。一个后台线程就足够了。我敢打赌,只需改变这个,你的性能就会更好。

我不建议直接从Activity中使用AsyncTask,因为它对配置更改很脆弱

我不建议使用精灵。在内存有限的移动设备上增加一个图像的大小非常危险。特别是对于精灵,你必须获取Bitmap的部分,因此需要将整个位图暂存在内存中。

现在我回答了你的具体问题,我认为你可以看一下ListView中的懒加载图片,因为问题非常相似。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接