在片段中选择使用AsyncTaskLoader还是AsyncTask的指南

30

请看 LoaderCustomSupport(使用AsyncTaskLoader)和FragmentRetainInstanceSupport(使用Thread,几乎等同于AsyncTask)。

这两个示例具有以下相似之处。

  • 在加载数据时,都不会阻塞UI线程
  • 当用户执行配置更改(如屏幕旋转)时,数据获取线程不会被销毁。
  • 当数据获取线程完成数据获取时,它可以更新到正确的Fragment UI。

然而,它们也有一些区别。

AsyncTaskLoader

  • 似乎没有简单的方法将中间进度更新到进度条对话框中

AsyncTask

  • 不确定。但是Android文档似乎推荐使用AsyncTaskLoader来进行异步数据加载和更新最终结果到UI?

是否有任何指南或清单可以查看,以决定选择AsyncTaskLoader还是AsyncTask来执行耗时的加载任务并将结果更新到Fragment的UI?

2个回答

26

你的问题引起了我的兴趣,我有时候会尝试研究它们之间的差异。这里是我的观察。

  1. 对于使用AsyncTask进行异步任务的过早终止,它将会在其线程中继续运行。结果的处理可能很快就会导致未请求的结果,而AsyncTaskLoader处理活动的过早终止。

  2. AsyncTaskLoader处理活动配置更改(例如,当用户旋转屏幕时)。

  3. AsyncTaskLoader旨在为DataAdapters加载数据,因此最好使用AsyncTaskLoader。但如果需要在任务完成后更改UI(特别是片段),则最好使用AsyncTask,因为您不能在AsynTaskLoader的onLoadFinished中更改片段。

因此,对我来说,使用取决于您的任务。如果上述3个要点不困扰您,则性能相同(虽然我没有找到任何文件,但在这种情况下,建议使用asynctaskloader:S)

一些相关链接

AsyncTaskLoader与AsyncTask

http://andreas-kluck.blogspot.com/2012/02/asynctask-and-asynctaskloader.html


关于您提到的第一点,“过早终止”是指AsyncTask还是整个Activity? - Kaveesh Kanwal

0

AsyncTaskLoaders,像所有的Loaders一样,旨在解决旋转问题。例如当一个AsyncTask被创建在一个Activity中,然后设备在任务完成之前发生旋转,那么该AsyncTask将会随着Activity的销毁而丢失。

虽然所有的Loaders目前都不支持发布进度,所以如果这是你的需求,那么你应该考虑另外的方法。如果旋转或其他导致Activity被销毁的事件并不是问题,那么直接使用AsyncTask即可;否则,你可能需要使用Service,并注册Binder来回传进度信息。

但在我看来,Service和Binder消息有些烦人。我发现一个更简单的解决方案是使用LocalBroadcastManager从IntentService(或AsyncTaskLoader)发送进度广播,并在Activity中添加BroadcastReceiver来接收和显示进度。


1
关于我在问题中提供的FragmentRetainInstanceSupport链接的注释。通过非UI片段的适当帮助,您也可以在AsyncTask中处理旋转。 - Cheok Yan Cheng
那么,您可以将异步任务放在非 UI 片段中,并通过活动将进度发布到 UI 片段 - 如果没有附加活动,则不会报告任何进度? - Sam
那么,如果一个AsyncTask正在运行而我旋转屏幕,那么AsyncTask会丢失吗?而在同样的情况下,AsyncTaskLoader不会丢失? - Kaveesh Kanwal
1
一般来说是的。您的Activity将丢失对AsyncTaskLoader的引用,但可以使用LoaderManager(类似于创建方式)来检索它。在developer.android.com上有大量有关正确实现Loader的文档。我还应该补充说,我的原始答案已经超过2年了。自那时以来,时间和我的喜好都发生了变化,如今我通常只使用RxJava(和单例模式)来管理通过配置更改(例如旋转)持续运行的操作。 - cephus

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