简体   繁体   English

Android AsyncTask vs Thread + Handler vs rxjava

[英]Android AsyncTask vs Thread + Handler vs rxjava

I know this is the question which was asked many many times. 我知道这是多次被问到的问题。 However there is something I never found an answer for. 然而,有些东西我从来没有找到答案。 So hopefully someone can shed me some light. 所以希望有人能给我一些启示。

We all know that AsyncTask and Thread are options for executing background tasks to avoid ANR issue. 我们都知道AsyncTask和Thread是执行后台任务以避免ANR问题的选项。 It is recommended that asynctask should only be used for short-running tasks while thread can be used for long-running tasks. 建议asynctask只应用于短期运行任务,而线程可用于长时间运行的任务。 The reasons why asynctask shouldn't be used for long tasks are well-known which is about the possible leak caused by asynctask since it may continue running after an activity's destroyed. asynctask不应该用于长任务的原因众所周知,这是因为asynctask可能导致泄漏,因为它可能会在活动被破坏后继续运行。 That is convincing. 这是令人信服的。 However, it also leads to some other questions: 但是,它还会导致一些其他问题:

  1. Isn't thread also independent from activity lifecycle? 线程是否也独立于活动生命周期? Thus, the risk with asynctask can also be applied to thread. 因此,asynctask的风险也可以应用于线程。 So why thread is suitable for long-running tasks? 那么为什么线程适合长时间运行的任务呢?
  2. Looks like the risk of asynctask is only applicable when using it with activity. 看起来asynctask的风险仅适用于与活动一起使用时。 If we use it in service (not IntentService since IntentService stops after its work's completed), and as long as we can guarantee to cancel the asyntask when the service's stopped, can we use it for long-running tasks? 如果我们在服务中使用它(不是IntentService,因为IntentService在其工作完成后停止),并且只要我们可以保证在服务停止时取消asyntask,我们可以将它用于长期运行的任务吗? and doesn't it means it's risk free to use asynctask in services? 并不意味着它可以在服务中使用asynctask吗?
  3. I've played with rxjava for a while and really like it. 我和rxjava玩了一段时间,真的很喜欢它。 It eliminates the need of worrying about threading (except you have to decide in which thread to subscribe and observe the emitted data). 它消除了担心线程的需要(除了你必须决定订阅哪个线程并观察发出的数据)。 From what I can see, rxjava (in conjunction with some other libs like retrofits) seems to be a perfect replacement of asynctask and thread. 从我所看到的,rxjava(与其他一些lib一起,比如改造)似乎是asynctask和thread的完美替代品。 I'm wondering if we could completely forget about them or there is any specific case that rxjava can't achieve what asynctask and thread can do that I should be aware of? 我想知道我们是否可以完全忘记它们,或者有任何特定的情况,rxjava无法实现asynctask和线程可以做的那些我应该知道的?

Thanks 谢谢

Since no one's replying. 既然没有人回复。 I'm answering my own questions then. 我正在回答我自己的问题。

  1. The reason why AsyncTask is recommended for only short tasks (around 5 seconds) is there is no method to cancel a running AsyncTask . AsyncTask建议仅用于短任务(大约5秒)的原因是没有方法可以取消正在运行的AsyncTask There exists a method called AsyncTask.cancel(true) which invokes onCancelled(Result result) . 存在一个名为AsyncTask.cancel(true)的方法,它调用onCancelled(Result result) However, according to the docs, this method "runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished." 但是,根据文档,这个方法“在调用cancel(boolean)并且doInBackground(Object [])完成后在UI线程上运行。” ( https://developer.android.com/reference/android/os/AsyncTask.html ). https://developer.android.com/reference/android/os/AsyncTask.html )。 On the other hand, Thread can be stopped with Thread.interrupt() . 另一方面,可以使用Thread.interrupt()停止Thread
  2. There shouldn't be any problem running an AsyncTask within a Service provided that you are aware of the cancellation limitation of AsyncTask and the possibility of memory leak can be created by AsyncTask . 如果您了解AsyncTask的取消限制并且可以通过AsyncTask创建内存泄漏的可能性,那么在Service运行AsyncTask应该没有任何问题。 Note that, there is obviously no need to use an AsyncTask in an IntentService which is already running in a worker thread. 请注意,显然不需要在已在工作线程中运行的IntentService使用AsyncTask
  3. This is a very experience-based question. 这是一个非常基于经验的问题。 I guess there would be no complete answer. 我想没有完整的答案。 What we can do is to understand Rx and being aware of the its limitations to determine where suitable to use it. 我们可以做的是了解Rx并意识到它的局限性,以确定适合使用它的位置。 In my development work, I use RxJava all the time without having any issue. 在我的开发工作中,我一直使用RxJava而没有任何问题。 Note that the same memory leaking issue is also applied to RxJava . 请注意,同样的内存泄漏问题也适用于RxJava You can perhaps find one of the specific questions here . 您也许可以在这里找到一个具体的问题。 There are also a whole bunch of discussions about handling leaking/screen rotation with RxJava that can be easily found by Googling. 关于使用RxJava处理泄漏/屏幕旋转的讨论还有很多,Googling可以很容易地找到它们。

AsyncTask and Thread+Handler are not carefully designed and implemented. AsyncTask和Thread + Handler没有经过精心设计和实现。 RxJava, Akka and other frameworks for asynchronous execution seem more carefully developed. RxJava,Akka和其他异步执行框架似乎更加精心开发。

Each technology has its limitations. 每种技术都有其局限性。 AsyncTask is for a single parallel task with ability to show progress on UI. AsyncTask用于单个并行任务,能够在UI上显示进度。 However, if activity is regenerated (eg because of screen rotating), connection to UI is lost (one possible solution for this problem is at https://github.com/rfqu/AsyncConnector ). 但是,如果重新生成活动(例如,由于屏幕旋转),则会丢失与UI的连接(此问题的一种可能解决方案是https://github.com/rfqu/AsyncConnector )。

Thread+Handler keeps memory for thread stack even when there is no messages to process. 即使没有要处理的消息, Thread+Handler也会为线程堆栈保留内存。 This limits the possible number of threads. 这限制了可能的线程数。 You can have much more Akka actors or RxJava Subscribers than handler threads, with similar functionality. 您可以拥有比处理程序线程更多的Akka actorsRxJava Subscribers ,具有类似的功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM