因此,我了解了有关AsyncTask的Android内存泄漏,从本质上讲,据我了解,是由于某种原因活动被销毁,但AsyncTask未完成,因此,由于AsyncTask对Activity具有强烈的引用,GC可以无法收集活动,即无法从内存中释放活动。我的问题是,如果/何时AsyncTask完成其工作且不再需要,那么GC为什么不能收集该引用的Activity?为什么会有问题?
答案 0 :(得分:0)
通常,内部类的寿命通常比其父辈长,这就是为什么父类不符合GC资格的原因。至于AsyncTask,如果执行您的异步任务inner
并为其提供活动的上下文,则Android Studio会警告它可能会导致内存泄漏。
此AsyncTask类应该是静态的,否则可能会发生泄漏(匿名android.os.AsyncTask)。静态字段将泄漏上下文。非静态内部类对其外部类具有隐式引用。例如,如果该外部类是Fragment或Activity,则此引用意味着长时间运行的处理程序/加载器/任务将持有对该活动的引用,从而防止该活动获取垃圾。同样,直接引用这些长时间运行的实例中的活动和片段可能会导致泄漏。 ViewModel类不应指向视图或非应用程序上下文。
非静态内部类失效为其父级。但是,当您不将其声明为internal时,意味着您不再有权访问父类成员。您可以传递对活动上下文的引用,但是同样会遇到内存泄漏的风险。
解决方案?
一个可能的解决方案是为您的上下文提供弱引用。另一个解决方案是取消活动的onStop()回调中的异步任务。此外,您可以使用activityContext.isFinishing()
确认活动状态。如果状态等于true
,只需取消或返回异步任务即可。
有点题外话。异步任务已经成为过去,还有其他更好的方法来处理并发,例如RxJava,Kotlin的协程等。