AsynTask更深的理解

来源:互联网 发布:网络编程 编辑:程序博客网 时间:2024/04/30 13:38

翻译自 stackoverflow.com/questions/12797550/android-asynctask-for-long-running-operations

Indeed AsyncTask have two main issues that are related :

  • they are poorly tied to the activity life cycle
  • the create memory leaks very easily.
事实上,关于AsyncTask有主要两个问题。

和activity生命周期有很差的关联性。

非常容易内存泄露。


The AsyncTask and Activity life cycle

AsyncTasks don't follow Activity instances' life cycle. If you start an AsyncTask inside an Activity and you rotate the device, the Activity will be destroyed and a new instance will be created. But the AsyncTask will not die. It will go on living until it completes.

And when it completes, the AsyncTask won't update the UI of the new Activity. Indeed it updates the former instance of the activity that is not displayed anymore. This can lead to an Exception of the type java.lang.IllegalArgumentException: View not attached to window manager if you use, for instance, findViewById to retrieve a view inside the Activity.

AsyncTask和Activity的生命周期。

AsyncTask并不知道Activity的生命周期是什么样的。如果你在Activity的内部创建一个AsyncTask然后你又旋转的设备,那么当Activity销毁时新的Activity实例会被创建,但是AsyncTask并不会死亡,它会一直运行的它完成任务之后。

然而当它完成任务之后,AsyncTask并不会更新新的Activity的UI。实际上,它之后更新那个不再显示的之前的那个Activity的实例。那么这就会导致IllegalArgumentException异常。


Memory leak issue

It is very convenient to create AsyncTasks as inner classes of your Activities. As the AsyncTask will need to manipulate the views of the Activity when the task is complete or in progress, using an inner class of the Activity seems convenient : inner classes can access directly any field of the outer class.

Nevertheless, it means the inner class will hold an invisible reference on its outer class instance : the Activity.

On the long run, this produces a memory leak : if the AsyncTask lasts for long, it keeps the activity "alive" whereas Android would like to get rid of it as it can no longer be displayed. The activity can't be garbage collected and that's a central mechanism for Android to preserve resources on the device.

内存泄露

AsyncTask作为Activity的内部类来创建实例的话是非常方便的。当AsyncTask在运行中或者完成任务时,由于它需要操纵Activity中的视图,使用Activity的内部类似乎是很方便的,但是内部类可以访问外围类的任何字段。

因此,这就意味着内部类会隐式的持有着外围实例的引用:Activity。

当长时间运行时,这会产生内存泄露。如果AsyncTask持续很长时间,它会保持Activity一直处于存活状态然而Android因为它不再显示也很想处理掉这个Activity。这个Activity不能被当成垃圾回收掉,而且它还持有着Android设备上的资源。


It is really a very very bad idea to use AsyncTasks for long running operations. Nevertheless, they are fine for short living ones such as updating a View after 1 or 2 seconds.

综上所述,对于想用AsyncTask来执行长时间的操作是一个非常非常不好的主意,对于使用一秒或者两秒来更新UI控件这样的短时间来讲使用AsyncTask是一个不错的选择。




0 0