0

我的应用程序中有一个ListView,每行都ListView需要从远程资源加载多个图像。(即列表视图看起来像 Instagram,其中每个项目至少包含一个图像)。

我正在实现两级缓存以改善加载图像体验:

  1. 我的一级内存缓存是这样定义的:

    private Map<String, SoftReference<Bitmap>> l1ImageCache = new HashMap<String, SoftReference<Bitmap>>();
    我可以在内存中保留一些图像的 SoftReference 以使应用程序查找更快。

  2. 我的二级文件缓存是 SD 卡或手机存储上的文件夹。我在那里保存了一些我已经下载的图像。如果应用程序在内存缓存中找不到图像,它将在文件目录中查找。如果图像文件存在,它将在本地加载文件并将文件引用也放入内存缓存中。

  3. 如果应用程序无法从内存缓存或文件缓存中找到所需的图像,它将使用ImageDownloadWorker(extends AsyncTask) 启动线程并下载图像。但是,android 每个应用程序最多只能允许 128 个线程,我正在考虑一种节省一些线程的方法。我创建了这个数据结构:

    // keep all pending downloads
    private HashMap<String, ImageDownloadWorker> downloadTaskMap = new HashMap<String, ImageDownloadWorker>();
    其中 String 字段将是要下载的 URL。这是为了检查下载某个 URL 的线程是否已经在运行,所以我不必启动另一个线程来下载相同的东西。

我的问题是根据代码,假设应用程序即将下载图像的情况。图像既不在内存缓存中,也不在下载的文件夹中。所以应用程序检查downloadTaskMap是否已经有一个线程正在下载这个文件,这样它就不必为同一件事创建一个新的 AsyncTask。但是我怎么知道这个挂起的下载任务何时完成而不阻塞主线程?如果我执行诸如等待/通知或无限循环之类的操作,我想知道这会阻塞 UI 线程吗?

欢迎指点,谢谢!

4

1 回答 1

0

首先,您不需要自己编写所有这些,有许多适用于 Android 的图像延迟加载解决方案。看这里,或者这里更好。

至于异步任务 - 它们不会同时运行,您应该使用普通Thread此答案executeOnExecutor的最新更新建议(否则您将无法在较新的设备上获得并行性)。顺便说一句,我认为您会发现该答案不仅有用。

于 2013-11-11T17:30:52.783 回答