执行后台任务 - AsyncTask的替代方案?

9
我希望在应用程序中有各种异步线程,例如5-10个线程,用于后台任务,这些任务可以是长时间运行的(例如流媒体),并且如果必要的话,我还会更新UI以发布一些结果。
据我所知,AsyncTask存在以下问题:
• 长时间运行的任务, • 与Activity生命周期绑定不良, • 设备方向问题, • 内存泄漏等。
因此,我正在寻找另一种替代方法(可能不使用任何第三方库),它不会出现上述问题。
如果使用简单的Java线程,是否更好? 如果它们不会出现与AsynTask相同的问题,那我不介意使用它们。

如果你想要一个与Activity/Fragment生命周期绑定的AsyncTask,那么你可以继承AsyncTaskLoader。顺便说一句,在许多设备上同时运行10个线程是不可能的,特别是在旧设备上,这意味着你需要有一个根据设备容量进行调整的算法。 - Enzokie
是的,不一定要一次性处理所有设备的10个,但这只是一种可能性,可以同时运行其中一些而不消耗大量资源。 - user963241
3个回答

6
在大多数情况下,AsyncTask应该足够满足需求。然而,在一些情况下,不能使用AsyncTask。例如,AsyncTask管理一个线程池,从中提取线程以供任务实例使用。现在,线程池假定它们会在合理的时间内取回它们的线程。因此,在你不知道需要多长时间的情况下,就不能使用AsyncTask。从Android 4.4开始,线程池的大小只能增加到:(CPU核心数×2)+1。因此,在双核处理器上,可以创建的最大线程数仅限于5。

所以,我正在寻找一个替代方案(可能不使用任何第三方库),它没有以上这些问题。

至于AsyncTask的替代方案,有以下可用选项:
  • Handler
  • Runnable
现在,无论如何美观地描绘后台线程,都存在缺点,其中一些包括:
  • 当后台线程正在处理时,用户交互的可能性。如果后台线程执行的工作发生变化,您需要将其传递回后台线程。 java.util.concurrent有许多类可帮助处理这些情况
  • 在线程执行任务时,进程本身可能被终止的可能性。因此,在这些情况下,而不是使用AsyncTask或更简单的ThreadServiceIntentService将是理想的选择。
  • 后台线程内部出现错误的可能性,例如在连接丢失时从服务器检索数据,您需要手动关闭后台线程。

简而言之:无论您选择哪个选项,都需要手动处理所有边角案例,以使应用程序高效而精彩地工作。

附注: [引用]:Commonsware的Android开发指南v5.8由@Commonsware发布,采用知识共享署名-非商业性使用-相同方式共享4.0许可证。

取决于情况,对于网络编程,已经存在一些非常强大的库。请参考此链接: https://github.com/shaheenkdr/awesome-android#networking - OBX
同样适用于REST API,包括Retrofit等。所有这些都可以进行广泛的定制。例如超时定制、带宽、连接质量、缓存、预取等,还有请求的适当取消等。 - OBX

3
  • 长时间运行的任务,
  • 与Activity生命周期捆绑不良,
  • 设备方向问题,以及
  • 内存泄漏等等。

简单的Java线程并不能解决这些问题。特别是内存泄漏问题。

如果你只是想在后台加载数据,可以考虑Loaders。它们会将数据缓存到整个应用程序中,并与活动/片段的生命周期很好地配合使用。

或者,你可以阅读这篇文章了解服务(如果你还不知道)并查看它们是否适合你的情况。


1
同意,因为内存泄漏是由不良实现引起的,而不是线程本身。 - Enzokie
请注意,服务不是AsyncTask的替代品,因为它们不会自动生成单独的线程。 - Code-Apprentice
是的,那是真的。 - mallaudin
好的,加载器没有设备方向问题。但是它们是否适用于长时间运行的任务,例如在后台下载大文件,如果屏幕关闭了,是否可以发布进度? - user963241
不,它们不是。在这种情况下,考虑使用一个服务。 - mallaudin

0

我首先建议使用上述组件,

  1. Handlers
  2. Runnables

如果操作时间较长,则可以选择服务,因为它会持续运行。你说过:

可能是长时间运行(例如流媒体)的任务

如果你正在播放音频或视频,则最好使用服务,普通 ServiceIntent Service 取决于你的需求。

在需要时可以随时销毁服务,或者让 Android 系统在必要时销毁它。

因此,在这种情况下,我建议您使用服务。


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