liangjingkanji / Serialize

🍒 Android 简单高性能读写本地数据, 直接存储对象/基础类型
http://liangjingkanji.github.io/Serialize/
Apache License 2.0
239 stars 20 forks source link

serial使用命名的规则有问题 #4

Closed lihuiqiang123 closed 2 years ago

lihuiqiang123 commented 2 years ago

存储数据key的问题

命名规则的逻辑,key的前缀使用类名拼接属性的名称,通过mmkv存储到磁盘的数据,只能在存储的当前页面使用,而其他页面因为类名不同,无法获取到通过mmkv存入到磁盘的数据。代码如下:

 override fun setValue(thisRef: Any?, property: KProperty<*>, value: V) {
        // 使用代理的对象的 class 名称
        val className = thisRef?.javaClass?.name
        // 属性名称或者自定义名称
        var adjustKey = name ?: property.name 
        // adjustKey 和使用代理的类绑定了,导致其他类无法获取到 adjustKey 
        // 除非提前知道哪个代理存储了数据,手动拼接代理类的className + name ,当然这种方式不现实。
        if (className != null) adjustKey = "${className}.${adjustKey}"
        kv.serialize(adjustKey to value)
    }

    override fun getValue(thisRef: Any?, property: KProperty<*>): V {
        val className = thisRef?.javaClass?.name
        var adjustKey = name ?: property.name
        if (className != null) adjustKey = "${className}.${adjustKey}"
        return if (default == null) {
            kv.deserialize(adjustKey)
        } else {
            kv.deserialize<V>(adjustKey, default)
        }
    }
liangjingkanji commented 2 years ago

serial数据本身就是依附于某个对象下的属性. 不同的类当然属于不同的数据. 你如果想所有地方都是用请创建object的字段

object AppConfig {
   var name:String? by serial()
}

只有bundle是取的当前页面的intent/argument里面的值, 而且也不是依附于页面

liangjingkanji commented 2 years ago

serial字段和普通字段唯一的区别就是他会自动映射到磁盘, 不存在什么不同页面同名称的字段依旧是同样的值

liangjingkanji commented 2 years ago

如果你既不想使用object又想随处可取. 你应当通过函数序列化

具体查看: https://liangjingkanji.github.io/Serialize/#_5

如果你觉得应当每个页面都存取同一个数据, 可以阐述下这样做的优势

lihuiqiang123 commented 2 years ago

例如有的需求是在一个设置页面进行app的一些开关设置,然后在其他页面根据开关的设置信息来进行不同的逻辑或者UI展示。 当然您提供的object类引用或者使用序列化化方法也可以解决这个问题。我个人觉得去掉引用类名作为name前缀的限制,可以使框架的serial方法在不影响之前的功能的前提上,功能性更强一点吧。

liangjingkanji commented 2 years ago

可是使用函数不是更简单么. 按照你的构想还得创建一个变量, 并且与serial还存在理解上的冲突

val name String? by newSerial() // 方案一, 你的构想

val name: String = deserialize("name") // 方案二, 现有使用, 甚至变量压根不需要创建

唯一优势是不需要指定name. 但是这样可能存在全局命名污染(kotlin废弃xml的Id引用就是因为此原因), 我也是主要担心这种情况出现超出预期的数据

lihuiqiang123 commented 2 years ago

你提供的函数使用deserialize获取存储到磁盘数据,没有问题。函数使用是直接使用,通过代理的方式算是间接使用,我只是在这个代理间接使用的时候有issue中的问题思考。函数使用比代理使用是更简洁的使用方式的话,是否使用代理或者代理中的问题思考就不算什么问题了。

liangjingkanji commented 2 years ago

如果有更好的想法也可以提PR给我, 我的思维某些方面可能也是狭隘了