使用 Kotlin 委托(Delegation) 实现 Android 中 SharedPreferences 的委托类

委托模式(代理模式)是一种常见的设计模式,委托模式使得我们可以用聚合来替代继承,将委托者与实际实现代码分离出来,以达成解耦的目的。关于更多代理模式的相关介绍,这里就不详细展开了,不了解的同学请自行 Google……

Kotlin 在语言层面原生支持委托模式。包括类的委托和属性的委托。

在 Android 里面,利用属性委托,我们可以以非常简单的方式来读写 preferences。我们可以创建一个委托,当 get 被调用时去读取 preferences 内容,当 set 被调用时去执行保存操作。

好了铺垫说完,下面直接上代码。

首先是 SharedPreferences 的委托类:

//采用泛型实现会方便我们处理各种类型的 preferences
class Preference(val context: Context, val name: String, val default: T)
    : ReadWriteProperty {
    val prefs by lazy {
        context.getSharedPreferences("default", Context.MODE_PRIVATE)
    }
    override fun getValue(thisRef: Any?, property: KProperty<*>)
            : T {
        return findPreference(name, default)
    }
    override fun setValue(thisRef: Any?, property: KProperty<*>,
                          value: T) {
        putPreference(name, value)
    }
    //读取 preferences
    private fun  findPreference(name: String, default: T): T = with(prefs) {
        val res: Any = when (default) {
            is Long -> getLong(name, default)
            is String -> getString(name, default)
            is Int -> getInt(name, default)
            is Boolean -> getBoolean(name, default)
            is Float -> getFloat(name, default)
            else -> throw IllegalArgumentException(
                    "This type can't be saved into Preferences")
        }
        res as T
    }
    //写入 preferences
    private fun  putPreference(name: String, value: U) = with(prefs.edit()) {
        when (value) {
            is Long -> putLong(name, value)
            is String -> putString(name, value)
            is Int -> putInt(name, value)
            is Boolean -> putBoolean(name, value)
            is Float -> putFloat(name, value)
            else -> throw IllegalArgumentException("This type can't be saved into Preferences")
        }.apply()
    }
}

下面我们再定义一个新的委托,这样我们可以更方便地访问 SharedPreferences 的委托类:

object mPreferenceDelegates {
    fun  preference(context: Context, name: String, default: T) = Preference(context, name, default)
}

使用,主要是两个全局单例:

//偏好设置键
object PreferenceKey{
    //偏好设置里是否接收消息推送的键
    val isReceiveMessage = "isReceiveMessage"
}

//访问用户偏好设置
object mPreferenceSetting{
    //是否接收消息推送,读写这条属性就相当于直接读写 preferences 里以 "isReceiveMessage" 为键的值
    var isReceiveMessage:Boolean by mPreferenceDelegates.preference(App.instance,PreferenceKey.isReceiveMessage,true)
}

最后,所谓用户偏好设置,就是首选项啦~

你可能感兴趣的:(使用 Kotlin 委托(Delegation) 实现 Android 中 SharedPreferences 的委托类)