android 委托列表,Kotlin的Android文件存储与委托(四)

1、数据存储读取文件

2、SharedPreferences

3、SharedPreferences简化

4、泛型的基本用法

5、类委托和委托属性

6、依靠委托自己实现个lazy

1、数据存储读取文件

fun saveString(context: Context, str: String) {

try {

val fileOutput = context.openFileOutput("data", Context.MODE_PRIVATE)

val bfs = BufferedWriter(OutputStreamWriter(fileOutput))

bfs.use {

it.write(str)

}

} catch (e: IOException) {

e.printStackTrace()

}

}

fun readString(context: Context): String {

val sb = StringBuilder()

try {

val openFileInput = context.openFileInput("data")

val bis = BufferedReader(InputStreamReader(openFileInput))

bis.use {

it.forEachLine {

sb.append(it)

}

}

} catch (e: Exception) {

e.printStackTrace()

}

return sb.toString()

}

由context的方法提供了openFileOutput方法,写入一个str如上述代码。

use是kotlin的一个内置函数,它保证在lambda表达式结束的时候会自动的流关闭。不用像以前要写finally去关闭流了。

2、SharedPreferences

val edit = getSharedPreferences("data", Context.MODE_PRIVATE).edit()

edit.putString("name", "1")

edit.apply()

val edit = getSharedPreferences("data", Context.MODE_PRIVATE)

edit.getString("name", "")

3、SharedPreferences简化

fun SharedPreferences.open(bolck: SharedPreferences.Editor.() -> Unit) {

val edit = edit()

edit.bolck()

edit.apply()

}

getSharedPreferences("data", Context.MODE_PRIVATE).open {

putString("name", "1")

}

扩展函数的高阶用法,之前的文章也有讲过类似的。

提供个我自己查资料封装的Sp,仅供参考:

object ShareUtils {

private val sharedPreferences: SharedPreferences

init {

sharedPreferences = App.context.applicationContext.getSharedPreferences(

"name",

Context.MODE_PRIVATE

)

}

fun putValue(name: String, value: T) = with(sharedPreferences.edit()) {

when (value) {

is Int -> putInt(name, value)

is Float -> putFloat(name, value)

is Long -> putLong(name, value)

is Boolean -> putBoolean(name, value)

is String -> putString(name, value)

else -> throw IllegalArgumentException("SharedPreference can't be save this type")

}.apply()

}

fun getValue(name: String, default: T): T = with(sharedPreferences) {

val res: Any? = when (default) {

is Int -> getInt(name, default)

is Float -> getFloat(name, default)

is Long -> getLong(name, default)

is Boolean -> getBoolean(name, default)

is String -> getString(name, default)

else -> throw IllegalArgumentException("SharedPreference can't be get this type")

}

return res as T

}

fun removeKey(name: String) = with(sharedPreferences.edit()) {

remove(name).apply()

}

}

4、泛型的基本用法

4.1类的泛型

class MyClass {

fun method(params: T): T {

return params

}

}

4.2方法的泛型

class MyClass {

fun method(params: T): T {

return params

}

}

val myClass = MyClass()

val method = myClass.method(123)

因为Kotlin有出色的类推导机制。

例如传入Int的参数,它就能自动推导出泛型的类型就是Int,所以上述的使用可以,不用传Int

val myClass = MyClass()

val method = myClass.method(123)

.

除此之外,Kotlin还可以对泛型的类型进行约束

class MyClass {

fun method(params: T): T {

return params

}

}

Number就是指定成数字类型。

4.3对泛型知识进行应用

fun T.build(block: T.() -> Unit): T {

block()

return this

}

val build = StringBuilder().build {

append("123123")

append("123123")

append("123123")

}

build.toString()

5、类委托和委托属性

委托的意思就是说把实现交给别的类来实现。就跟定义接口,写这个接口的实现类一样,

class MyClass(val helper: HashSet) : Set{

override val size: Int

get() = helper.size

override fun contains(element: T): Boolean {

return helper.contains(element)

}

override fun containsAll(elements: Collection): Boolean {

return helper.containsAll(elements)

}

override fun isEmpty(): Boolean {

return helper.isEmpty()

}

override fun iterator(): Iterator {

return helper.iterator()

}

}

我把HashSet作为参数传入,并且让类继承Set接口。

就上述代码看的话,会发现有些方法是我必须重写的。如果这个方法几十个或者更多的时候, 这样写肯定是非常繁琐的。于是我加了个by

class MyClass(val helper: HashSet) : Set by helper {

override val size: Int

get() = helper.size

override fun contains(element: T): Boolean {

return helper.contains(element)

}

}

Kotlin委托的关键字是By,我们只需要在接口后面声明,使用by,再加上受委托的对象即可。这样的话,我就不需要重写那么多的样板代码了,根据选择重写实现。并且我还仍然可以使用委托类的属性。

委托属性

class MyClass {

var p by ImplTest()

}

class ImplTest {

var pro: Any? = null

operator fun getValue(myClass: MyClass, property: KProperty): Any? {

return pro

}

operator fun setValue(myClass: MyClass, property: KProperty, any: Any?) {

pro = any

}

}

将p委托给了ImplTest。

这样在给p赋值的时候就会调用 setValue方法。如果p是val声明的话, 那就在初始第一次的时候赋值,接下来一直调用getValue就好。

set/getValue,第一个参数是指的委托功能可以在什么类中使用。第二个参数是 属性操作类,此处没有什么用,但是必须要声明,不声明编译过不去。

6、依靠委托自己实现个lazy

class latter(val block: () -> T) {

var value: Any? = null

operator fun getValue(any: Any?, property: KProperty): T {

if (value == null) {

value = block()

}

return value as T

}

}

fun later(block: () -> T) = latter(block) //kt文件

上述意思就是 支持任意的类型, 并且在获取之前判断是否为空,为空的话执行block逻辑,做了一个简易的缓存。

val name by later {

println("1312321312313")

}

在声明later之后, 如果没有调用的话,是不会打印出来值的,可以在activity中写个按钮或者别的, 调用name。 来验证实现类懒加载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值