当我使用返回键关闭Android应用程序并重新进入时,发现我的两个单例类中的变量从未被重新初始化,因此出现了一些奇怪的问题(如果使用任务管理器手动杀死应用程序,则不会出现此问题)。
即使在主Activity的onBackPressed上明确调用finish并且可以看到onDestroy已经被调用,但Singletons仍然存在于内存中。
我决定在销毁我的Activity之前进行这些Singletons的手动清理,但问题是使用Kotlin,我需要将它们的所有成员变量变为可空的(?),而且记得给每一个变量赋值为null会很麻烦。所以目前我选择像这样处理Singleton的实例化,并在清理时将整个实例都设置为null:
class SingletonName {
companion object {
private var _instance: SingletonName ? = null
private var instance: SingletonName ?
get() {
if (_instance == null) {
_instance = SingletonName ()
}
return _instance
}
set(value) {
_instance = value
}
@JvmStatic fun get(): SingletonName {
return instance!! //avoid having to deal with nullable value in client code
}
}
//need to make sure to call this before destroying main activity
fun cleanup() {
instance = null
}
}
客户端使用:
SingletonName.get().somefunc()
这似乎比应该要复杂,而且我知道这甚至不是线程安全的,但请记住,仅仅使用“object”关键字而不是“class”是行不通的,因为它会阻止任何初始化发生第二次运行应用程序(构造函数不会再次被调用,我无法强制销毁实例)。
这让我觉得值得研究Android依赖注入,但我觉得至少我的一个Singleton确实需要在很多地方访问,所以它可能也不是一个优雅的解决方案(可能需要将其重构为更小的功能)。
主要问题在于android处理销毁的方式,但我想我不能改变那个,如果应用程序活动已经被销毁,我不明白为什么它仍然保留所有非活动类的静态值。
问题是,无论使用哪种语言,你如何处理这些情况?或者你认为在这种情况下最好的做法是什么?
编辑:实际上,我刚刚用Dagger 2进行了测试,相同的问题发生了,如果我使用@Provides和@Singleton,提供的对象的成员变量的值第二次启动应用程序时不为null,所以我想这需要显式处理,除非我错过了一些更多的注释来告诉Dagger实例应该在应用程序生命周期结束时释放。
recreate
或其他类似的方法来重新初始化你的单例。 - Mibacandroid.app.Application
将在整个应用程序的生命周期中存在。如果您想要一个生存期较短、带有 UI 并且可以在配置更改后继续存在的对象,请考虑使用onRetainCustomNonConfigurationInstance
。 - Miha_x64