kotlin-委托属性以及在SharedPreferences中的应用

一,属性委托

有一些常见的属性类型,虽然我们可以在每次需要的时候手动实现他们,但是如果能够为大家把他们只实现一次并放入一个库会更好,例如包括

  • 延迟属性(lazy properties):其值只在首次访问时计算
  • 可观察性属性(observable properties):监听器会收到此属性变更的通知
  • 把多个属性存储在一个映射(map)中,而不是存在没个单独字段中

为了涵盖这些(以及其他)情况,kotlin支持委托属性:

语法是:val/var<属性名>:<类型> by <表达式> 在by后面的表达式是该委托,因为属性对应的get()和set()会被委托给它的getValue()和setValue()方法,属性的委托不必实现任何的接口,但是需要提供一个getValue()和setValue()->对于var属性

class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name} in $thisRef.'")
    }
}

class Example{
    val d = Delegate()
    val e = Delegate()
    var p: String by d
    var l: String by e
}

fun main(args: Array<String>){
    val e = Example()
    println(e.p)
    e.p = "NEW"
    println(e.l)
    e.l = "NEW.L"
    println(e.d)
    println(e.e)
}

输出结果:
com.xp.kotlin.part1.Example@300ffa5d, thank you for delegating ‘p’ to me!
NEW has been assigned to ‘p in com.xp.kotlin.part1.Example@300ffa5d.’
com.xp.kotlin.part1.Example@300ffa5d, thank you for delegating ‘l’ to me!
NEW.L has been assigned to ‘l in com.xp.kotlin.part1.Example@300ffa5d.’
com.xp.kotlin.part1.Delegate@1f17ae12
com.xp.kotlin.part1.Delegate@4d405ef7

当我们从委托到一个Delegate示例的p读取是,将调用Delegate中的getValue()函数,所以它的第一个参数是读出p的对象,第二个参数保存了对p自身的表述(例如你可以取它的名字)

从上面输出我们可以看出 每次委托的时候都要new新的对象。

二,委托属性之SharedPreferences工具类应用

有了属性委托,当我们在用Kotlin写SharedPreferences工具类的时候,就会变得更加简单和易读。

class Preference<T>(private val key: String, private val default: T) : ReadWriteProperty<Any?, T> {
    companion object {
        val preference: SharedPreferences by lazy { BaseApplication.INSTANCE.applicationContext.getSharedPreferences(Constant.SHARED_NAME, Context.MODE_PRIVATE) }
        fun clear() {
            preference.edit().clear().apply()
        }
    }

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return getSharePreference(key, default)
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        return putSharePreference(key, value)
    }

    @Suppress("UNCHECKED_CAST")
    private fun <T> getSharePreference(key: String, default: T): T = with(preference) {
        val value: Any = when (default) {
            is Long -> getLong(key, default)
            is String -> getString(key, default)
            is Int -> getInt(key, default)
            is Boolean -> getBoolean(key, default)
            is Float -> getFloat(key, default)
            else -> throw IllegalArgumentException("This type of data can not be saved! ")
        }
        value as T
    }

    @SuppressLint("CommitPrefEdits")
    private fun <T> putSharePreference(key: String, default: T) = with(preference.edit()) {
        when (default) {
            is Long -> putLong(key, default)
            is String -> putString(key, default)
            is Int -> putInt(key, default)
            is Boolean -> putBoolean(key, default)
            is Float -> putFloat(key, default)
            else -> throw IllegalArgumentException("This type of data can not be saved! ")
        }.apply()
    }
}

我们知道SharedPreference是用来存储一些基本数据类型的数据的。当我们存储指定数据类型的时候。我们可以使用泛型并在when中进行判断。然后进行get和put操作。

private var isLogin: Boolean by Preference(Constant.KEY_LOGIN, false) //取值or默认值 会调用getValue()

isLogin = true //赋值 会调用setValue()方法

三,总结

  • 委托属性使我们的代码更加的简洁和优雅,可读性更高。
  • 每次在by的时候都要new一个新的对象,这个在工具类中使用感觉不是很好,感觉不如单例好(个人猜想)

示例代码:https://github.com/wangxp423/ExerciseKt

kotlin之Android项目实战

猜你喜欢

转载自blog.csdn.net/wangxp423/article/details/80736193