我的应用中有一个ListView
,ListView
的每一行都需要从远程资源加载多个图像。(即listview看起来像Instagram,其中每个项目至少包含一个图像)。
我正在实现一个两级缓存来改善负载图像体验:
我的第一级内存缓存定义如下:
private Map<String, SoftReference<Bitmap>> l1ImageCache = new HashMap<String, SoftReference<Bitmap>>();
我可以在内存中保留一些图像的SoftReference,以便更快地查找应用程序。
我的二级文件缓存是SD卡或手机存储上的文件夹。我在那里保存了一些已下载的图像。如果应用程序无法在内存缓存中找到该图像,它将在文件目录中查找。如果图像文件存在,它将在本地加载文件并将文件引用也放入内存缓存中。
如果应用无法从内存缓存或文件缓存中找到所需的图像,它将使用ImageDownloadWorker
(扩展AsyncTask
)启动线程并下载图像。但是,android每个应用程序只允许多达128个线程,我正在考虑保存一些线程的方法。我创建了这个数据结构:
// keep all pending downloads
private HashMap<String, ImageDownloadWorker> downloadTaskMap =
new HashMap<String, ImageDownloadWorker>();
其中String字段将是要下载的URL。这是为了检查下载某个URL的线程是否已经在运行,所以我不必启动另一个线程来下载相同的东西。
我的问题是根据代码,假设应用程序即将下载图像的一个案例。图像既不在内存缓存中,也不在下载的文件夹中。因此,应用程序检查了downloadTaskMap
是否已有线程下载此文件,因此它不必为同一事物创建新的AsyncTask。 但是如何在不阻止主线程的情况下知道此挂起的下载任务何时完成?如果我做一些像wait / notify或者一些无限的while循环,我想知道这会阻止UI线程吗?
欢迎指点,谢谢!
答案 0 :(得分:0)
首先,您不需要自己编写所有内容,有许多适用于Android的图像延迟加载解决方案。请参阅here,或者更好地关闭here。
对于异步任务 - 它们不会同时运行,您应该使用普通Thread
或executeOnExecutor
作为this answer建议的最新更新(否则您将无法获得并行性)在较新的设备上)。顺便说一句,我认为你会发现这个答案不仅仅是单一的方式。