Android 快速位图加载

发布于 2025-01-06 13:43:33 字数 483 浏览 2 评论 0原文

我有一块图像想要加载到屏幕上。所有图像都是我下载并存储在 SD 卡上的文件。

到目前为止,我找到了两种方法来做到这一点,首先是在活动开始时将它们加载到主线程上(我得到了大约 70 张图像,大约需要 2.1 秒才能加载全部图像)。

另一种方法是我现在正在测试的。将它们加载到单独的线程上,因此同时我可以为用户显示加载动画。目前,我使用 ThreadPoolExecutor 的实现花费了 4.3 秒。我是用 10 个线程完成的。

最后一种方法(这是我唯一尚未测试的方法)是使用精灵表。

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

您认为加载大量图像最快的方法是什么以及您知道哪些加速技术可以帮助我?

I have a block of images that I want to load on my screen. All the images are files that I downloaded and stored on SD-CARD.

So far I found two ways to do it, first is loading them on the main thread, when the activity is starting, (I got about 70 images and it takes me about 2.1 seconds to load them all).

Another way is what I am testing right now. Load them on separated thread, so meanwhile I can show loading animation for the user. For now my implemintation with ThreadPoolExecutor took 4.3 sec. I did it on 10 threads.

And the last method, (it's the only thing that I didn't test yet) is working with sprite sheet.

I can't use application cache because in my application I have lots of screens and each screen has its own images set.

What do you think, what is the fastest way to load large amount of images and what acceleration technics do you know that can help me up?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

撑一把青伞 2025-01-13 13:43:33
  1. 不要在主线程上加载。延迟 2.1 秒后,如果您阻塞主线程,您几乎会因 ANR(应用程序未响应)错误而被杀死。

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

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

  1. Don't load on main thread. With 2.1 sec delay you're close to being killed with ANR (app not responding) error if you block main thread.

  2. Load in separate thread. Don't create 10 threads, but one AsyncTask, and load all your images one after another in doInBackground.

    Loading in AsyncTask should take (nearly) same time as loading in main thread. Don't put too much fancy animations, so that main thread doesn't consume too much CPU time.

苍风燃霜 2025-01-13 13:43:33

一种选择是使用 Wea​​kReference 创建图像缓存,以便在系统遇到内存不足的情况时从内存中删除图像。这样您就可以将图像保留在内存中,并且仅当图像不在内存中时才需要从 SD 卡加载。因此,您当前的活动将始终保留对所需位图的硬引用,而图像缓存将保留对位图的弱引用。

以下是有关弱引用的更多信息:

JavaDocweakReference

< a href="https://stackoverflow.com/questions/6116395/what-are-the-benefits-to-using-weakreferences">StackOverflow 帖子讨论使用弱引用进行缓存

One option would be to use create image cache using the WeakReference so that the image would be removed from the memory when system encounter low memory situation. This way you can keep images in memory and only need load from sdcard when they are not in memory. So your current activity would always keep the hard reference to the bitmap's required and the image cache would keep the weak reference to the bitmap's.

Following is some more information about weak reference:

JavaDoc weakReference

StackOverflow post discussing using weak reference for cache

浪推晚风 2025-01-13 13:43:33

实现此目的的一种方法是实现一种侦听器/观察器。

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

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

或者,您也可以检查加载程序在您的情况下的执行情况。

One way to do this will be to implement a kind of listener/observer.

From your UI thread, launch other thread that will load the image. Once the image is loaded, thread will invoke a call back method implemented in the activity class to update the corresponding image view.

Instead of android asynch task, I will go for my threads (pooled/Executors). I will get all the possible image paths before loading them, and dispatching them to thread loading the image.And in the call back I know where to updated the image.

Alternatively you can also check how the Loader perform in your case.

转角预定愛 2025-01-13 13:43:33

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

我认为 ThreadPoolExecutor 是一个很好的解决方案,但在池中创建许多线程并不是最佳选择。在后台线程上就足够了。我敢打赌,只需更改此设置,您就会获得更好的性能。

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

我不建议使用精灵。对于内存有限的移动设备来说,增加一张图像的大小是非常危险的。特别是对于精灵,您必须获取位图的一部分,因此内存中会暂时保留完整的位图。

既然我没有回答你的具体问题,我想你会经历 在列表视图中延迟加载图像,因为问题非常相似。

Clearly, you should not leave a 2s-long operation in the UI thread.

I suppose the ThreadPoolExecutor is a godd solution, but it is not optimal to create many threads in your pool. On background thread is sufficient. I bet you'll have better performance simply by changing this.

I don't recommend an AsyncTask directly from the Activity, because it is fragile to config change.

I don't recommend working with sprites. Increasing the size of one image is very dangerous on a mobile where memory is limited. In particular with sprites, you'll have to get parts of the Bitmap, hence having the full bitmap in memory for a moment.

Now that I unanwsered your specific questions, I think you go throuh Lazy loading of images in a listview because the problem is very similar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文