Kotlin与伴生对象

738 阅读1分钟

最近在通过MVVM-Rhine学习kotlin,看到SharedPreferences的管理类的写法倍感困惑

UserInfoRepository

class UserInfoRepository(prefs: SharedPreferences) {

    var accessToken: String by prefs.string("user_access_token", "")

    var username by prefs.string("username", "")

    var password by prefs.string("password", "")

    var isAutoLogin: Boolean by prefs.boolean("auto_login", true)

    companion object :
            SingletonHolderSingleArg<UserInfoRepository, SharedPreferences>(::UserInfoRepository)
}

首先UserInfoRepository中的伴生对象传入的了::UserInfoRepository,虽然没查到这种写法的文档出处,但应该是代表UserInfoRepository的主构造函数。

SingletonHolderSingleArg

open class SingletonHolderSingleArg<out T, in A>(private val creator: (A) -> T) {

    @Volatile
    private var instance: T? = null

    fun getInstance(arg: A): T =
            instance ?: synchronized(this) {
                instance ?: creator(arg).apply {
                    instance = this
                }
            }
}

SingletonHolderSingleArg的主构造器中,传入一个方法,这个方法接收A类型的参数,返回T类型的对象。在SingletonHolderSingleArg#getInstance中,先判断单例对象instance是否为空,然后根据传入的方法生成T类型的对象instance

UserInfoRepository中,伴生对象SingletonHolderSingleArg接收了一个函数,这个函数是SingletonHolderSingleArg主构造函数,它接收唯一实例SharedPreferences,得到UserInfoRepository实例。所以SingletonHolderSingleArg#getInstance的作用是获取UserInfoRepository单例对象。

所以最终可以通过依赖注入sp后,随意的调用UserInfoRepository的属性,这里面还涉及到属性的委托。// todo