Как разработчик Android, я много раз слышал, что View (Activity / Fragments) не должен содержать никаких ссылок на объекты с более длинным жизненным циклом (например, Application), иначе GC не сможет собрать его и произойдет утечка памяти.
Но сегодня я попытался воспроизвести эту проблему и получил неожиданный результат - GC все еще собирает Activity, даже если она имеет ссылку на класс Application.
Я запустил его на 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, чтобы принудительно убить активность
Скомпилируйте код выше
Закройте (сверните) приложение и откройте его несколько раз. MainActivity.onCreate запускается каждый раз, когда я закрываю / открываю Activity
Закрыть (свернуть) приложение
-x-> через 10-30 секунд я получил журнал, что все созданные действия были завершены (сборщик мусора)
---> созданные действия не должны собираться мусором, поскольку они содержат ссылку на класс Application
Кто-нибудь знает, почему это происходит? Значит ли это, что нам вообще не нужно беспокоиться об утечках активности? :)
PS Я также сделал ту же проблему без опции "Не сохранять действия"