我已经阅读了上述两个原因/问题:
(请在下面的链接中阅读两个原因)
Android AsyncTask for Long Running Operations
1."如果在Activity中启动AsyncTask并旋转设备,则将销毁Activity并创建新实例。但是AsyncTask不会死掉":
让我们假设我已将活动的方向设置为肖像。这个问题还会出现吗?
2.内存泄漏问题:
内部类将在其外部类实例上保存一个不可见的引用:活动
如果我没有使用Inner AsyncTask而是创建单独的类,该怎么办?如果我使用弱参考。
答案 0 :(得分:4)
您提到的问题只有在AsyncTask的生命周期处理不当时才会出现,主要是因为缺乏对其工作方式的理解。
AsyncTask是在单独的线程上运行代码的包装器。它类似于提交给Runnable
的普通Java ExecutorService
,其中“pre”和“post”钩子的其他功能可以在主线程上运行。所以,它基本上是Thread
,Runnable
和Handler
设置的增强版本。
默认情况下,AsycTask共享一个线程,因此不建议长时间运行的任务。因为当许多任务共享单个后台线程时,长时间运行的任务可能会阻止其他任务。但是,AsycTask也可以在自定义Executor
上运行,从而消除了对共享工作线程的限制。
所有这些意味着AsyncTask自己的设计不会限制其长期运行任务的使用。
您可以让后台Service
在单独的ThreadPoolExecutor
上使用AsyncTasks运行一些连续处理。
您可以使用AsyncTask加载Fragment
最新消息,当调用Fragment的onDestroy()
时,您取消该任务,因为它不再有意义。
因此“多长时间和AsyncTask应该运行”的答案完全取决于使用情况。
答案 1 :(得分:1)
设置方向将起作用,因为锁定到纵向意味着没有方向更改,这意味着没有生命周期重新创建。但是,如果一项活动暂停很长时间,它仍然可以被销毁,所以这不是一个确保100%工作的好方法。您可以尝试a service or a headless fragment。
根据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
可以在任何情况下使用,但通常使用它比使用它更简单。