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

Posted

技术标签:

【中文标题】执行后台任务——AsyncTask 的替代方案?【英文标题】:Performing Background Tasks – alternative to AsyncTask? 【发布时间】:2017-06-17 17:27:51 【问题描述】:

我想在应用程序中有各种异步线程,例如 大约 5-10 个线程,用于可以长时间运行(如流式传输)的后台任务,我也是 更新 UI 以在必要时发布一些结果。

据我所知,AsyncTask 存在以下问题:

长时间运行的任务, 与 Activity 生命周期的关联不佳, 设备方向问题,以及 内存泄漏等等。

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

我应该使用简单的 Java 线程更好吗?我不介意使用它们,因为它们不会给 AsynTask 带来任何问题。

【问题讨论】:

如果您想要一个与 Activity/Fragment 生命周期相关联的 AsyncTask,那么您可以对 AsyncTaskLoader 进行子类化。顺便说一句,对于这么多设备特别是在旧设备上运行 10 个线程是不可能的,这意味着您需要有一个基于设备容量进行扩展的算法。 是的,不一定对所有设备一次 10 个,但这可能只是在不消耗大量资源的情况下并行运行其中一些设备的可能性。 【参考方案1】:

在大多数情况下,AsyncTask 应该足以满足要求。但是,在某些情况下无法使用AsyncTask。即AsyncTask 管理一个线程池,它从中提取线程以供任务实例使用。现在线程池假设他们会在一段合理的时间后恢复他们的线程。因此,在您不知道线程需要多长时间的情况下,您不能使用AsyncTask。从 android 4.4 开始,线程池的大小只能增长到:(no of CPU cores * 2) + 1。所以在双核处理器上,你可以创建的最大线程数限制为 5 个。

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

来到AsyncTask 的替代品,这些是可用的选项:

处理程序 可运行

现在所有后台线程都有缺点,无论它们多么精美,包括:

后台线程正在处理时用户交互的可能性。如果后台线程执行的工作被更改,您需要将其传达回后台线程。 java.util.concurrent 有许多类可以在这些情况下提供帮助 线程执行任务时进程本身被杀死的可能性。因此,在这些情况下,而不是使用 AsyncTask 或更简单的 Thread ServiceIntentService 将是一个理想的选择。 后台线程内部可能发生错误,例如在连接丢失时从服务器检索数据,您需要手动关闭后台线程。

简而言之:无论您选择哪个选项,您都需要手动处理 应用程序高效和出色运行的所有极端情况。

PS: [引用]:The busy coder's guide to Android development v5.8@Commonsware,根据知识共享署名非商业性相同方式共享 4.0 许可发布

【讨论】:

视情况而定,对于网络,已经存在一些非常强大的库,请参见:github.com/shaheenkdr/awesome-android#networking 也适用于 REST apis ,Retrofit 也是如此。所有这些都可以在很大程度上进行定制。像超时自定义、带宽、连接质量、缓存、预取以及正确取消请求等。【参考方案2】: 长时间运行的任务, 与 Activity 生命周期的关联不佳, 设备方向问题,以及 内存泄漏等等。

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

如果你只是想在后台加载数据,你可以考虑Loaders。它们在应用程序范围内缓存数据,并很好地适应活动/片段生命周期。

或者,您可以通过this 文章了解服务(如果您还不知道),看看它们是否适合您的场景。

【讨论】:

同意,因为内存泄漏是由错误的实现而不是线程本身引起的。 请注意,Services 不是 AsyncTask 的替代品,因为它们不会自动生成一个单独的线程。 是的。没错。 好的,加载程序没有设备方向问题。但是它们是否适合长时间运行的任务,例如在后台下载大文件?如果屏幕可以关闭,是否可以发布进度? 不,他们不是。在这种情况下考虑使用服务。【参考方案3】:

我首先建议使用上面提到的组件,

    处理程序 可运行文件

如果该操作长时间运行,那么您可以在它连续运行时进行维修。你说

可以长时间运行(如流式传输)

如果您通过某些音频或视频进行流式传输,那么最好根据您的要求使用普通的ServiceIntent Service 服务。

您可以在需要时销毁服务,或让 Android 系统在需要时销毁。

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

【讨论】:

以上是关于执行后台任务——AsyncTask 的替代方案?的主要内容,如果未能解决你的问题,请参考以下文章

android中的asynctask可不可以并行执行多个

通过AsyncTask访问后台后得到的返回数据在Android端显示

AsyncTask介绍

Android攻城狮AsyncTask

在后台线程执行硬任务,在主线程返回结果

Android AsyncTask详解