为什么AsyncTask完成后,Android无法从内存中释放完成的活动?

时间:2019-04-30 19:43:57

标签: android android-asynctask garbage-collection

因此,我了解了有关AsyncTask的Android内存泄漏,从本质上讲,据我了解,是由于某种原因活动被销毁,但AsyncTask未完成,因此,由于AsyncTask对Activity具有强烈的引用,GC可以无法收集活动,即无法从内存中释放活动。我的问题是,如果/何时AsyncTask完成其工作且不再需要,那么GC为什么不能收集该引用的Activity?为什么会有问题?

1 个答案:

答案 0 :(得分:0)

通常,内部类的寿命通常比其父辈长,这就是为什么父类不符合GC资格的原因。至于AsyncTask,如果执行您的异步任务inner并为其提供活动的上下文,则Android Studio会警告它可能会导致内存泄漏。

  

此AsyncTask类应该是静态的,否则可能会发生泄漏(匿名android.os.AsyncTask)。静态字段将泄漏上下文。非静态内部类对其外部类具有隐式引用。例如,如果该外部类是Fragment或Activity,则此引用意味着长时间运行的处理程序/加载器/任务将持有对该活动的引用,从而防止该活动获取垃圾。同样,直接引用这些长时间运行的实例中的活动和片段可能会导致泄漏。 ViewModel类不应指向视图或非应用程序上下文。

非静态内部类失效为其父级。但是,当您不将其声明为internal时,意味着您不再有权访问父类成员。您可以传递对活动上下文的引用,但是同样会遇到内存泄漏的风险。

解决方案?

一个可能的解决方案是为您的上下文提供弱引用。另一个解决方案是取消活动的onStop()回调中的异步任务。此外,您可以使用activityContext.isFinishing()确认活动状态。如果状态等于true,只需取消或返回异步任务即可。

有点题外话。异步任务已经成为过去,还有其他更好的方法来处理并发,例如RxJava,Kotlin的协程等。