当前位置: 首页 > 面试题库 >

Android中的WeakReference / AsyncTask模式

高高雅
2023-03-14
问题内容

我对android中这种简单的经常发生的情况有疑问。

我们有一个main活动,我们调用一个AsyncTask以及mainactivity的引用,以便AsyncTask可以更新MainActivity上的视图。

我将把事件分解成几个步骤

  • MainActivity创建一个AyncTask,并将其引用传递给它。
  • AysncTask,开始工作,例如下载十个文件
  • 用户更改了设备的方向。这将导致AsyncTask中的孤立指针
  • 当AsyncTask完成并尝试访问活动以更新状态时,由于空指针,它崩溃了。

上述解决方案是按照《 Pro Android 4》一书的建议在AsyncTask中保留WeakReference。

WeakReference<Activity> weakActivity;

in method onPostExecute

Activity activity = weakActivity.get();
if (activity != null) {
   // do your stuff with activity here
}

如何解决这种情况?

我的问题是,如果我的asynctask正在下载十个文件,并且在完成5个文件后,活动重新启动(由于方向更改),那么我的FileDownloadingTask是否会再次调用?

最初调用的先前AsyncTask会发生什么?

谢谢,对于这个问题,我深表歉意。


问题答案:

如何解决这种情况?

WeakReference允许Activity进行垃圾回收,所以你不要有内存泄漏。

空引用意味着AsyncTask 不能
盲目尝试更新不再附加的用户界面,这将引发异常(例如,未附加到窗口管理器的视图)。当然,您必须检查是否为空以避免NPE。

如果我的asynctask正在下载十个文件,并且在完成5个文件后,活动重新启动(由于方向更改),那么我的FileDownloadingTask是否会再次调用?

取决于您的实现,但可能是这样-如果您不故意做一些不必要的重复下载操作,例如将结果缓存在某个地方。

AsyncTask最初调用的那个会发生什么?

在早期版本的Android中,它可以运行到完成,下载所有文件只是为了丢弃它们(或缓存它们,具体取决于您的实现)。

在较新的Android操作系统中,我怀疑AsyncTasks和Activity它们的启动都被杀死了,但我怀疑的依据只是RoboSpice的内存泄漏演示(见下文)实际上并未泄漏到我的JellyBean设备上。

如果我可以提供一些建议:AsyncTask不适合执行可能长时间运行的任务,例如联网。

IntentService如果您可以接受单个工作线程,则是一种更好(但仍然相对简单)的方法。Service如果要控制线程池,请使用(本地)-注意不要在主线程上工作!

如果您正在寻找一种在后台可靠地执行联网的方法,RoboSpice看起来不错(免责声明:我没有尝试过;我没有隶属关系)。Play商店中有一个RoboSpice
Motivations演示应用程序
,它通过演示所有可能出错的地方(包括WeakReference解决方法)来说明
为什么 要使用它AsyncTask

更新:

我创建了一个github项目,并提供了一个下载示例,该示例IntentService用于另一个SO问题(如何修复android.os.NetworkOnMainThreadException?),但我认为在这里也很重要。它具有附加的优势,即通过onActivityResult旋转返回结果时,在旋转设备时正在进行的下载将传递给重新启动的Activity



 类似资料:
  • 本文向大家介绍简介Android 中的AsyncTask,包括了简介Android 中的AsyncTask的使用技巧和注意事项,需要的朋友参考一下 AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合。其实AsyncTask并不是那么好,甚至有些糟糕。本文我会讲AsyncTask会引起哪些问题,如何修复这些问题,并且关于AsyncTask的一些替代方案。 Async

  • 问题内容: 一个简单的问题:是否可以返回in的值? 然后在我的: 编辑:这是很久以前我不熟悉Java的地方问的,现在我对它有了更好的了解,我将做一个简短的总结: 异步任务的要点是该任务为,这意味着调用该任务后,该任务将在其自己的线程上开始运行。从asynctask返回一个值将毫无意义,因为原始的调用线程已经进行了其他工作(因此该任务是异步的)。 考虑时间:在某个时间点,你启动了一个将与主线程并行运

  • 问题内容: 我正在阅读有关的内容AsyncTask,并尝试了以下简单程序。但这似乎不起作用。我该如何运作? 我只是想在后台处理5秒后更改标签。 这是我的main.xml: 问题答案: 好的,您正在尝试通过另一个线程访问GUI。基本上,这不是一个好习惯。 在另一个线程内部执行所有操作,该线程无法访问您的视图所在的GUI。 并在此新线程发生繁重之前和之后为您提供访问GUI的权限,甚至可以将long操作

  • 本文向大家介绍详解Android中AsyncTask机制,包括了详解Android中AsyncTask机制的使用技巧和注意事项,需要的朋友参考一下 在Android当中,提供了两种方式来解决线程直接的通信问题,一种是通过Handler的机制,还有一种就是今天要详细讲解的 AsyncTask 机制。 AsyncTask                                         

  • 本文向大家介绍Android中AsyncTask详细介绍,包括了Android中AsyncTask详细介绍的使用技巧和注意事项,需要的朋友参考一下 AsyncTask是一个很常用的API,尤其异步处理数据并将数据应用到视图的操作场合。其实AsyncTask并不是那么好,甚至有些糟糕。本文我会讲AsyncTask会引起哪些问题,如何修复这些问题,并且关于AsyncTask的一些替代方案。 Async

  • 本文向大家介绍详解Android中AsyncTask的使用方法,包括了详解Android中AsyncTask的使用方法的使用技巧和注意事项,需要的朋友参考一下 在Android中实现异步任务机制有两种方式,Handler和AsyncTask。 Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,