考慮下面的超類:
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