为什么AsyncTask不适合长时间运行

时间:2015-11-20 12:22:40

标签: java android android-asynctask

我已经阅读了上述两个原因/问题:
(请在下面的链接中阅读两个原因)
Android AsyncTask for Long Running Operations
1."如果在Activity中启动AsyncTask并旋转设备,则将销毁Activity并创建新实例。但是AsyncTask不会死掉":
让我们假设我已将活动的方向设置为肖像。这个问题还会出现吗?

2.内存泄漏问题:
内部类将在其外部类实例上保存一个不可见的引用:活动 如果我没有使用Inner AsyncTask而是创建单独的类,该怎么办?如果我使用弱参考。

5 个答案:

答案 0 :(得分:4)

您提到的问题只有在AsyncTask的生命周期处理不当时才会出现,主要是因为缺乏对其工作方式的理解。

AsyncTask是在单独的线程上运行代码的包装器。它类似于提交给Runnable的普通Java ExecutorService,其中“pre”和“post”钩子的其他功能可以在主线程上运行。所以,它基本上是ThreadRunnableHandler设置的增强版本。

默认情况下,AsycTask共享一个线程,因此不建议长时间运行的任务。因为当许多任务共享单个后台线程时,长时间运行的任务可能会阻止其他任务。但是,AsycTask也可以在自定义Executor上运行,从而消除了对共享工作线程的限制。

所有这些意味着AsyncTask自己的设计不会限制其长期运行任务的使用。

您可以让后台Service在单独的ThreadPoolExecutor上使用AsyncTasks运行一些连续处理。

您可以使用AsyncTask加载Fragment最新消息,当调用Fragment的onDestroy()时,您取消该任务,因为它不再有意义。

因此“多长时间和AsyncTask应该运行”的答案完全取决于使用情况。

答案 1 :(得分:1)

  1. 设置方向将起作用,因为锁定到纵向意味着没有方向更改,这意味着没有生命周期重新创建。但是,如果一项活动暂停很长时间,它仍然可以被销毁,所以这不是一个确保100%工作的好方法。您可以尝试a service or a headless fragment

  2. 根据this帖子,弱引用会解决内存问题

答案 2 :(得分:1)

AsyncTask的其他问题:丢失结果

是的,你说:

  

假设我已将活动的方向设置为肖像。   这个问题还会存在吗?

但是,Activity不仅可以重新创建'导致轮换。例如,如果系统中没有足够的资源,操作系统可能会破坏您的活动。

因此,对于长时间运行的操作,AsyncTask在活动重新播放后onPostExecute()中对其活动的无效引用存在高风险。

另一个问题:并行

new AsyncTask1().execute();
new AsyncTask2().execute();

这两个任务是同时运行还是AsyncTask2在AsyncTask1完成时启动? 嗯......这取决于 API级别

大量的API级别......

在API 1.6(甜甜圈)之前:任务是连续执行的。这意味着任务不会在上一个任务完成之前启动。

API 1.6到API 2.3(Gingerbread):Android开发团队更改了AsyncTasks,以便在单独的工作线程上并行启动它们。

API 3.0(Honeycomb):再次串行执行的AsyncTasks。当然,Android团队提供了让他们并行运行的可能性。这是通过方法executeOnExecutor(Executor)完成的。查看API文档以获取更多相关信息。

答案 3 :(得分:0)

AsyncTask有以下缺点。

<强> 1。内存泄漏: - 在内部类以及seprate类中,在两种情况下都提供了对AsyncTask进行回调的活动的引用AsyncTask不会释放导致内存泄漏的GC活动引用。

<强> 2。 GC: - 如果AsyncTask正在运行,尽管调用活动被销毁,它将限制GC不运行,直到它无法完成其过程。

第3。 On Orintation 更改活动将重新创建,因为Asynchtask将在后台运行,当它完成其操作时,它将尝试更新导致IllegalStateException的UI,因为活动未附加到窗口。

因此,如果您将Service用于长时间运行的后台进程而不是AsyncTask,那就更好了。

答案 4 :(得分:0)

围绕这个话题有很多迷信,很难知道从哪里开始。 AsyncTask只是标准任务队列周围的一小块糖,使用它或不使用它与其他事物相比没有多大区别。

例如,方向改变的问题不是真实的。您可以在活动第一次启动时启动AsyncTask,而不是在下次启动时启动它。 (并记住配置中的其他更改也可以重新启动您的活动。)

弱参考是完全矫枉过正,可能会让你无处可去。你要么需要参考当前的活动(然后弱的参考不能工作),要么不需要(然后,根本不要持有任何参考)。

你问题中最重要但缺失的是你真正想要实现的目标吗?

想想有人在你的应用程序运行时接听他们的电话,并在一段时间后回到它。然后尝试回答以下问题:   - 15分钟前的结果是否相关?或者重启任务?   - 6个小时前怎么样?   - 如果后台任务中断,会发生什么不好的事吗?   - 用户是否期望完成任务? (他按下&#34; OK&#34;等待确认出现?)。

然后然后你可以问一个更精确的问题。 AsyncTask可以在任何情况下使用,但通常使用它比使用它更简单。