在Kotlin中,委托属性(Delegated Properties)是一种强大的语言特性,允许你将属性的 getter 和 setter 方法的实现委托给其他对象。这使得你能够通过委托来重用代码、将属性的行为解耦,并实现一些通用的模式。下面是一些关键概念和用法:

classExample {varproperty: String by Delegate()
}
classDelegate {operator fun getValue(thisRef: Any?, property: KProperty<*>): String {//获取属性值的实际实现 return "Delegated value"}operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {//设置属性值的实际实现 println("Setting value to: $value")
}
}

在上面的代码中,Example类中的property属性的访问,比如,访问example.property,就会委托到Delegate.getValue; 属性值的设置example.property = "str",就会委托到

Delegae.setValue。

实际例子:

   fun saveCookie(url: String?, domain: String?, cookies: String) {
url
?: return varspUrl: String by Preference(url, cookies)
@Suppress(
"UNUSED_VALUE")
spUrl
=cookies
domain
?: return varspDomain: String by Preference(domain, cookies)
@Suppress(
"UNUSED_VALUE")
spDomain
=cookies
}

var spUrl: String by Preference(url, cookies),定义一个委托属性spUrl,Preference委托,执行spUrl = cookies,会将这个setValue的动作委托到Preference类中的setValue。

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
putSharedPreferences(name, value)
}

其中value的值是cookies.如果要访问spUrl,那么,对应的getValue方法,会被委托到Preference中的getValue方法中去。

总结来说:

委托属性,就是将一个属性的getValue方法和setValue方法委托到另外一个代理类来实现。将属性的获取和设置隔离开来。

class Preference<T>(val name: String, private val default: T) {

companion
object{private val file_name = "wan_android_file" privateval prefs: SharedPreferences by lazy {
App.context.getSharedPreferences(file_name, Context.MODE_PRIVATE)
}
/**
* 删除全部数据
*/fun clearPreference() {
prefs.edit().clear().apply()
}
/**
* 根据key删除存储数据
*/fun clearPreference(key: String) {
prefs.edit().remove(key).apply()
}
/**
* 查询某个key是否已经存在
*
* @param key
* @return
*/fun contains(key: String): Boolean {returnprefs.contains(key)
}
/**
* 返回所有的键值对
*
* @param context
* @return
*/fun getAll(): Map<String, *>{returnprefs.all
}
}
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {return getSharedPreferences(name, default)
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
putSharedPreferences(name, value)
}

@SuppressLint(
"CommitPrefEdits")private fun putSharedPreferences(name: String, value: T) =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 ->putString(name, serialize(value))
}.apply()
}

@Suppress(
"UNCHECKED_CAST")private fun getSharedPreferences(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 -> deSerialization(getString(name, serialize(default)) ?: "")
}
return res asT
}
/**
* 序列化对象

* @param person
* *
* @return
* *
* @throws IOException
*/@Throws(IOException::class)private fun <A>serialize(obj: A): String {
val byteArrayOutputStream
=ByteArrayOutputStream()
val objectOutputStream
=ObjectOutputStream(
byteArrayOutputStream
)
objectOutputStream.writeObject(obj)
var serStr = byteArrayOutputStream.toString("ISO-8859-1")
serStr
= java.net.URLEncoder.encode(serStr, "UTF-8")
objectOutputStream.close()
byteArrayOutputStream.close()
returnserStr
}
/**
* 反序列化对象

* @param str
* *
* @return
* *
* @throws IOException
* *
* @throws ClassNotFoundException
*/@Suppress("UNCHECKED_CAST")
@Throws(IOException::
class, ClassNotFoundException::class)private fun <A>deSerialization(str: String): A {
val redStr
= java.net.URLDecoder.decode(str, "UTF-8")
val byteArrayInputStream
=ByteArrayInputStream(
redStr.toByteArray(charset(
"ISO-8859-1"))
)
val objectInputStream
=ObjectInputStream(
byteArrayInputStream
)
val obj
= objectInputStream.readObject() asA
objectInputStream.close()
byteArrayInputStream.close()
returnobj
}

}

标签: none

添加新评论