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

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

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

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

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

首先是 SharedPreferences 的委托类:

//采用泛型实现会方便我们处理各种类型的 preferences
class Preference<T>(val context: Context, val name: String, val default: T)
    : ReadWriteProperty<Any?, T> {
    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 <T> 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 <U> 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 <T : Any> 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)
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 176,016评论 25 709
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,502评论 9 118
  • Google在今年的IO大会上宣布,将Android开发的官方语言更换为Kotlin,作为跟着Google玩儿An...
    蓝灰_q阅读 77,114评论 31 489
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,882评论 19 139
  • 一、简评电影《雨人》 珍视着亲情并竭力去守护他们的哥哥雷蒙如果只是单纯有着先天缺陷的人,那么这部电影不过成了饱含温...
    冰雪声阅读 2,920评论 0 0

友情链接更多精彩内容