Android AsyncTask 对比 Thread + Handler 对比 rxjava

Android AsyncTask vs Thread + Handler vs rxjava

我知道这是被问过很多次的问题。但是,有些事情我从未找到答案。所以希望有人能给我一些启示。

我们都知道AsyncTask 和Thread 是执行后台任务以避免ANR 问题的选项。建议 asynctask 仅用于短运行 任务,而线程可用于长运行 任务。 asynctask 不应该用于长任务的原因是众所周知的,这与 asynctask 可能导致的泄漏有关,因为它可能会在 activity 被销毁后继续 运行。这是有说服力的。然而,这也导致了一些其他问题:

  1. 线程不是也独立于activity生命周期吗?因此,异步任务的风险也可以应用于线程。那么为什么thread适合long-运行的任务呢?
  2. 看起来 asynctask 的风险仅在与 activity 一起使用时才适用。如果我们在服务中使用它(不是 IntentService,因为 IntentService 在其工作完成后停止),只要我们能保证在服务停止时取消 asyntask,我们可以将它用于 long-运行 任务吗?这不意味着在服务中使用 asynctask 是没有风险的吗?
  3. 我已经使用 rxjava 玩了一段时间并且非常喜欢它。它消除了担心线程的需要(除非您必须决定在哪个线程中订阅和观察发出的数据)。据我所知,rxjava(结合其他一些库,如改造)似乎是 asynctask 和线程的完美替代品。我想知道我们是否可以完全忘记它们,或者有任何特定情况 rxjava 无法实现我应该注意的 asynctask 和线程可以做的事情?

谢谢

AsyncTask和Thread+Handler没有经过精心设计和实现。 RxJava、Akka等异步执行的框架似乎更用心开发。

每种技术都有其局限性。 AsyncTask 适用于单个并行任务,能够在 UI 上显示进度。但是,如果 activity 重新生成(例如由于屏幕旋转),与 UI 的连接将丢失(此问题的一个可能解决方案位于 https://github.com/rfqu/AsyncConnector)。

Thread+Handler 即使没有要处理的消息,也会为线程堆栈保留内存。这限制了可能的线程数。您可以拥有比具有类似功能的处理程序线程更多的 Akka actorsRxJava Subscribers

因为没有人回复。那我来回答我自己的问题。

  1. 之所以只建议将 AsyncTask 用于短任务(大约 5 秒),是因为没有取消 运行 AsyncTask 的方法。存在一个名为 AsyncTask.cancel(true) 的方法,它调用 onCancelled(Result result)。但是,根据文档,此方法 "runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished." (https://developer.android.com/reference/android/os/AsyncTask.html)。另一方面,Thread 可以用 Thread.interrupt() 停止。
  2. 运行一个Service内的一个AsyncTask应该没有任何问题,前提是你知道AsyncTask的取消限制和记忆的可能性AsyncTask 可造成泄漏。请注意,显然没有必要在工作线程中已经是 运行 的 IntentService 中使用 AsyncTask
  3. 这是一个很靠经验的问题。我想不会有完整的答案。我们能做的是理解 Rx 并意识到它的局限性,以确定适合使用它的地方。在我的开发工作中,我一直使用 RxJava 没有任何问题。请注意,同样的内存泄漏问题也适用于 RxJava。您也许可以找到其中一个具体问题 。还有一大堆关于使用 RxJava 处理 leaking/screen 旋转的讨论,可以通过谷歌搜索轻松找到。