考虑下面的超类:
open class MySuperClass(val context: Context) {...}
由于科特林对象只有一个空的构造,你需要类似的结构以下几点:
// Private constructor is only accessible within the class.
class MySingleton private constructor(context: Context) : MySuperClass(context) {
companion object {
lateinit var INSTANCE: MySingleton
// Instance setter is only accessible from within the class.
private set
// Custom init function is called from outside and replaces
// THE WHOLE SINGLETON with a new instance
// to avoid internal dependencies on the old context.
fun init(context: Context) {
INSTANCE = MySingleton(context.applicationContext)
}
}
// Lazily initialized field dependent on a Context instance.
val prefs by lazy { PreferenceManager.getDefaultSharedPreferences(context) }
}
您需要使用单独的类之前调用init(context)
一次,Application
是一个伟大的地方做。每次Instant Run加载一个新的Application
对象时,这也会创建一个新的单例实例,以便始终以最新的应用程序上下文结束。
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Eagerly initialized singleton.
MySingleton.init(this)
}
}
注:
- 科特林对象只有一个空的构造。如果您需要初始化对象,请使用自定义的初始化函数。
- 如果您的字段取决于可能发生变化的上下文,则最好使用
class
而不是object
,并自行管理当前实例。如果您需要将参数传递给您的单身人士的超类,您也必须这样做。
- 因为你热切(未在
getInstance(context)
第一次调用初始化你的应用程序的启动类这是一个伟大的想法,懒洋洋地你单身的对象内的重物。
- 如果你的程序是多进程找到一种方法来初始化你的单例只在你实际使用它的过程中(提示:ContentProvider默认只在主进程中创建。)
如果你知道如何在Java中而不是在Kotlin中实现你想要的,有两件事情:1)你应该/可以用Java实现该位并与Kotlin进行交互; 2)IntelliJ IDEA提供在IDE中将Java自动转换为Kotlin。 – Whymarrh
@Whymarrh 1)我知道,但我想问一些关于kotlin的知识(如果有人有更好的解决方案)。 2)好主意,不记得了。 – lampenlampen