Android AsyncTask与Thread + Handler与RxJava的比较

12
我知道这个问题已经被问了很多次,但有一些东西我从来没有找到答案。希望有人能给我一些启示。
我们都知道AsyncTask和Thread是执行后台任务的选项,以避免ANR问题。建议只使用asynctask来处理短时间运行的任务,而线程可以用于长时间运行的任务。为什么asynctask不应该用于长时间运行的任务,原因是关于可能由asynctask引起的泄露问题,因为它可能在activity销毁后继续运行。这很有说服力。然而,这也引出了一些其他问题:
1. 线程不也独立于activity的生命周期吗?因此,与asynctask相关的风险也可以适用于线程。那么为什么线程适合长时间运行的任务呢?
2. 看起来asynctask的风险只适用于在activity中使用。如果我们在服务中使用(asynctask),并且只要我们保证在服务停止时取消asynctask,我们是否可以将其用于长时间运行的任务?这是否意味着在服务中使用asynctask是无风险的?
3. 我已经使用rxjava一段时间了,真的很喜欢它。它消除了担心线程的需要(除非您必须决定在哪个线程中订阅和观察已发射的数据)。从我所看到的情况来看,rxjava(与一些其他库如retrofits结合使用)似乎是asynctask和线程的完美替代品。我想知道我们是否可以完全忘记它们,或者是否有任何特殊情况,rxjava不能实现asynctask和线程所能做的事情,我应该注意什么?
谢谢
2个回答

3

由于没有人回复,我就自己回答我的问题。

  1. AsyncTask 推荐只用于短时间任务(大约5秒以内),因为没有方法可以取消正在运行的 AsyncTask。存在一个称为 AsyncTask.cancel(true) 的方法,它会调用 onCancelled(Result result)。但是,根据文档,该方法“在调用 cancel(boolean) 并且 doInBackground(Object[]) 已经完成后在 UI 线程上运行。”(https://developer.android.com/reference/android/os/AsyncTask.html)。另一方面,Thread 可以通过 Thread.interrupt() 停止。
  2. 在意识到 AsyncTask 的取消限制和可能导致内存泄漏的情况下,将 AsyncTask 运行在一个 Service 中不应该出现任何问题。请注意,已经在工作线程中运行的 IntentService 不需要使用 AsyncTask
  3. 这是一个非常基于经验的问题。我想可能没有完整的答案。我们所能做的就是了解 Rx 并意识到其限制,以确定在何处适合使用它。在我的开发工作中,我一直使用 RxJava 而没有遇到任何问题。请注意,相同的内存泄漏问题也适用于 RxJava。您可以在 此处 找到其中一个具体问题。还有一堆关于如何处理使用 RxJava 时的内存泄漏和屏幕旋转的讨论,这些都可以通过谷歌轻松找到。

0

AsyncTask和Thread+Handler的设计和实现并不是很仔细。RxJava、Akka和其他用于异步执行的框架似乎更加精心开发。

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

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


谢谢你的回答。这意味着总是使用RxJava而不是Asynctask和Thread吗?你能否请澄清一下你在回答中所说的“小心谨慎”是什么意思?谢谢。 - H.Nguyen

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