Android AsyncTask vs Thread + Handler vs rxjava

时间:2016-10-05 00:37:08

标签: android multithreading android-asynctask rx-java android-handler

我知道这是多次被问过的问题。然而,有些东西我从来没有找到答案。所以希望有人能给我一些启示。

我们都知道AsyncTask和Thread是执行后台任务以避免ANR问题的选项。建议asynctask只应用于短期运行任务,而线程可用于长时间运行的任务。 asynctask不应该用于长任务的原因众所周知,这是因为asynctask可能导致泄漏,因为它可能会在活动被破坏后继续运行。这是令人信服的。但是,它也会导致其他一些问题:

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

2 个答案:

答案 0 :(得分:1)

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

  1. 为短期任务(约5秒)推荐AsyncTask的原因是没有方法可以取消正在运行的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内运行Service应该没有任何问题,前提是您知道AsyncTask的取消限制,并且可以通过{创建内存泄漏的可能性{1}}。请注意,显然不需要在AsyncTask中使用已在工作线程中运行的AsyncTask
  3. 这是一个非常基于经验的问题。我想没有完整的答案。我们可以做的是了解Rx并意识到它的局限性,以确定适合使用它的位置。在我的开发工作中,我一直使用IntentService而没有任何问题。请注意,同样的内存泄漏问题也适用于RxJava。您也许可以找到一个具体问题here。关于使用RxJava处理泄漏/屏幕旋转的一系列讨论也很容易通过谷歌搜索找到。

答案 1 :(得分:0)

AsyncTask和Thread + Handler未经过精心设计和实现。 RxJava,Akka和其他异步执行框架似乎更加精心开发。

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

即使没有要处理的消息,

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