【问题标题】:Android Threading - Executing One thread before all others are executedAndroid线程 - 在执行所有其他线程之前执行一个线程
【发布时间】:2012-07-23 02:08:35
【问题描述】:

我是 Android 编程新手,遇到线程问题。

我基本上使用来自 50 个左右 URL 的图像填充 GridView,但是在我从已知 URL 检索 JSON 对象之前,这些 URL 不会被知道。我知道我必须为每个 URL 下载启动一堆线程(使用 AsyncTask 类)。

如何有效地将这些线程排队,以便 JSON 线程首先执行和完成,这样当我立即启动这 50 个图像线程时,我可以使用从该线程检索到的数据?

【问题讨论】:

    标签: android multithreading android-asynctask


    【解决方案1】:

    不要启动 50 个线程。使用单线程。虽然这应该与 UI 线程分开以实现响应性,但不需要生成多个线程,当然也不需要每个 URL.ce 一个线程

    只需进行 JSON 网络调用,然后解析响应,然后(在同一个线程中)循环请求每个 URL,并将结果解码为位图。您让他们在某个模型对象中将它们添加到您的 GridView 的适配器中,这将自动触发 GridView 在 UI 线程上更新。

    这里有一些更好的做法,例如延迟加载、缓存和在加载图像时显示占位符图像,但确切的实现变得过于复杂,无法在此处描述。搜索 WeakReferenceMap 和 LruCache 以查找将动态图像加载到 AdapterView 的最佳实践示例。

    【讨论】:

    • 所以,这是 50 个连续的 DNS 查找和 50 个连续的 HTTP GET 请求。为什么说单线程是一种好方法,尤其是考虑到无线链路的延迟?
    • 因为如果您并行启动 50 个请求,您的用户将在其中任何一个完成加载之前退出应用程序。
    • 我基本上是在按照android-developers.blogspot.com/2010/07/… 的方式做一些事情,它不会一次做 50 个,只是当前在 gridview 中的任何事情。它工作正常。这不是问题每当 gridview 中的网格元素尝试填充自身时,就会创建一个新线程
    • @MarkRenouf - 为什么?多个并发的 DNS 查找等在桌面应用程序上工作正常。有什么问题?
    【解决方案2】:

    好吧,您可以只运行第一次 fetch,完成后,从该主线程触发 50 个线程。当您从 UI 线程进行网络通信时,Android 3.0 及更高版本会终止您的应用程序,AsyncTask 可能是获取 JSON 的一种方式。当它返回时,它可能会触发其他线程。

    您仍应考虑的一件事是,尽管 Android 功能强大,但仍然是功能有限的设备。 50 个线程可能会使用目标手机拥有的更多资源,因此您的应用程序可能会被系统杀死(例如,因为 OOME)。所以在桌面上 50 个线程听起来并不多,但在手机上却很多。

    另外,IIrc,http 规范中有一个限制,一个远程服务器只能有 4 个(?)同时连接。因此,请考虑将图像加载请求排队并一个接一个地获取它们。

    【讨论】:

    • 我正在使用 AsyncTask 检索图像(使用虚拟 URL)。这工作正常。但我不确定如何组织这些线程,以便在另一个 AsyncTask 线程检索到该 JSON 对象之前基本上不会触发
    • 不只是图像加载,首先是 DNS 请求。尽管如此,四个线程和一个生产者-消费者队列肯定会比一个线程快,并且在资源有限的移动设备中,限制为 4 似乎是一个合理的开始。我可能会使其可配置,以便我可以轻松尝试不同的线程池深度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多