作为Android开发人员,我已经多次听到View(Activity / Fragments)不应包含对生命周期较长的对象的任何引用(例如Application),否则GC无法收集它,并且会发生内存泄漏。
但是今天,我试图重现此问题并得到意外的结果–即使它引用了Application类,活动仍由GC收集。
我在3个设备(api:22、24、28)上运行它,并得到了相同的结果。
这是我用于测试的代码:
查看:
class MainActivity : AppCompatActivity() {
var gcBlocker = ApplicationContext.inst.list
override fun onCreate(savedInstanceState: Bundle?) {
Log.d("custom_masher", "CREATE!")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
gcBlocker.forEach {
Log.d("app", it.toString())
}
}
fun finalize(){
Log.d("custom_masher", "FINALIZE!")
}
}
应用程序:
class ApplicationContext : Application() {
var list = listOf<Int>(1, 2, 3)
companion object {
lateinit var inst:ApplicationContext
}
override fun onCreate() {
super.onCreate()
inst = this
}
}
我如何复制它:
在Android设备的“开发人员”选项中打开“不保留活动”以强制杀死活动
编译上面的代码
关闭(最小化)应用程序,然后再次打开它几次。每次我关闭/打开Activity时都会触发MainActivity.onCreate
关闭(最小化)应用程序
-x-> 10-30秒后,我得到所有创建的活动都已完成(收集垃圾)的日志
--->创建的活动不应被垃圾回收,因为它们包含对Application类的引用
有人知道为什么会这样吗?这是否意味着我们完全不必担心活动泄漏? :)
PS我也做了同样的问题,没有“不保留活动”选项
答案 0 :(得分:0)
Okey,当我想起基本的GC术语时,我已经意识到了这一点:)
当根对象(应用程序)无法丰富收集的对象时,GC收集一个对象。
在我的案例中,尽管MainActivity引用了Application实例,但是Application实例仍然无法提供任何MainActivity方法或属性,因此,当Android发布活动时,该活动将由GC收集。
如果我已将Activity引用或回调传递给Application类,则GC将不会收集MainActivity。