安卓活动/服务中的多个线程

4
我有一个安卓应用,其中在列表视图中,对于列表中的每个元素,我会在单独的线程中从网络加载一张图片。所以如果在列表视图中显示8个项目,则该活动将尝试启动8个不同的线程,为每个列表项加载一张图片。当你向下滚动列表时,如果之前的线程尚未执行完毕,则线程数量可能会增加。
我很好奇一个单一的安卓应用可以并行执行多少个同时线程?是否有限制?我不认为这些线程会因为它们是相互独立的而导致慢速互联网连接引起ANR(应用无响应)错误。但似乎ANR确实会发生,可能是由于应用/设备资源不足,因此在UI中生成新活动需要超过5秒钟,这会导致ANR?
如果你有任何关于如何在慢速互联网连接上使响应更好的线索,将不胜感激。
2个回答

6
后来我发现我的应用程序挂起和运行缓慢并不是因为它生成了太多的线程。相反,是因为我使用了 Service 而不是 IntentService。而且我的网络 IO 是在 Service 的主线程中进行的。这意味着阻塞 IO 会使主线程阻塞,手机/应用程序将倾向于崩溃并弹出 ANR。
后来,我改变了设计,将网络 IO 操作放在 Services 中生成的线程中,这让应用程序重新焕发生机。一切都像预期一样更加流畅。
因此,每当您的服务导致 ANR 时,请确保如果您没有使用 IntentService(它们在单独的线程中触发作业),则在新线程中触发阻塞操作。
希望这能对某些人有所帮助。

5

处理这个问题的一种方法是使用线程池。我不知道同时运行的线程数量是否有限制,但创建和销毁它们是昂贵的。使用线程池,您可以拥有有限数量的线程来执行任务。

一个线程完成任务后可以被重用,这会带来性能提升。

如果有更多需要同时完成的工作而您没有足够的线程来执行它,您需要将工作排队等待线程空闲。


那么,如果我在列表视图中使用异步任务来加载图像,而不是生成新的线程,那么对于每个列表项,它是否会使用相同的AsyncTask和相同的线程池,还是会使用不同的AsyncTask和不同的线程池? - Priyank
1
@Priyank 我相信CommonsWare的意思是AsyncTask在其实现中使用线程池。因此,当您创建AsyncTask时,它可能会重用旧线程而不是创建新线程。这有助于减少对象创建,从而减少了垃圾回收等需求。如果您真的想同时下载100个图像,每个图像都在不同的线程上,那么它就没有那么有用了。但是,如果您先下载5个,然后几秒钟后再下载另外5个,您可能会看到性能提高。 - Cheryl Simon

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