最近在通过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