利用Kotlin委托实现优雅地持久化存储应用配置。
- 支持纯Kotlin项目
- 支持Android项目
- 支持自定义持久化实现
- 空安全
- 配置动态监听
这里可以使用注解 @Config("app_config", implCls = ...) 配置存储文件名,多个配置类可分文件存储。
安卓项目可以无需指明implCls,自动使用 SharedPreference 做存储;使用数据库需要适配,参考: 自定义持久化实现
- 定义配置类
//注解非必须,不加注解,会使用默认配置路径,和默认存储实现 @Config("app_config", implCls = JsonSettings::class) object AppConfig { //基本类型存储 var text: String by smartKey("a") //可空基础类型 var nullableInt: Int? by smartKey(null) var number: Int by smartKey(50) //数组 var intArr: Array<Int> by smartKey(emptyArray()) //实体类 var userInfo: UserInfo? by smartKey(null, encrypt = true) //实体数组 [操作即更新] 默认空列表 var modelList by smartKeyList<ListModel>() //实体集 [操作即更新] 默认空集 var modelSet by smartKeySet<ListModel>(emptySet()) // [操作即更新] var map by smartKeyMap<String, Int>() } //数组实体 data class ListModel(val s: String, val a: Int) //实体类 data class UserInfo( var name: String, var email: String, var age: Int )
- 此时你可以像这样使用
//获取存储值 val value = AppConfig.text val n = AppConfig.number //实时存储 AppConfig.text = "setValue" AppConfig.number = 0 //存储登录用户数据 val user = UserInfo("new_user", "xx@xx.xx", 0) AppConfig.userInfo = user //注意修改实体中的属性无法触发持久化操作 user.name = "hello" //需要赋值操作触发 AppConfig.userInfo = user //操作 实时存储 无需显式赋值;需要注意避免循环 add, 可以使用addAll AppConfig.modelList.add(ListModel("string", 1)) //set map 操作同 List 实时存储
- 配置类附加功能
继承BaseConfig拥有配置类基础操作
object AppConfig : BaseConfig { //... }
// 清空此配置所有key AppConfig.clear() // 直接存储key AppConfig["key"] = 1 //key, value AppConfig["text"] = "abc" //key, value // 加密储存(目前只支持String及实体类型加密) AppConfig["key", true] = "value" "key" in AppConfig // is contains key AppConfig -= "key" // remove key // 获取可空类型的值 val strNullable: String? = AppConfig["dont_exists_key"] //提供默认值 以获取不可空值 val s :String = AppConfig["text", "default"] //key, default // 获取解密后的数据 val value :String? = AppConfig["key", true] //获取可空数据 val user :UserInfo? = AppConfig["userInfo"] // or val user = AppConfig.get<UserInfo?>("userInfo") //获取加密内容 val user: UserInfo? = AppConfig["userInfo", true]
见app目录
- 你可以指定变量对应存储的key:
object AppConfig2 : BaseConfig { //指定key //import cn.vove7.smartkey.smartKey var text: String by smartKey("defaultValue", key = "your_key") var textWithKey: String by smartKey("aaa", key="text_key") //安卓项目可通过resId指定keyId //import cn.vove7.smartkey.android.smartKey var textAndroid: String by smartKey("defaultValue", keyId = R.string.key) }
- key 动态绑定
print(AppConfig2.textWithKey) //aaa AppConfig2["text_key"] = "bbb" print(AppConfig2.textWithKey) //bbb
- 选择是否加密数据:
//使用encrypt来声明加密存储数据 var userInfo: UserInfo? by smartKey(null, encrypt = true)
- 为每个配置类设置存储实现
不指定
implCls时, 默认实现为JsonSettings
@Config(implCls = FileSettings::class) class AppConfig1 { } @Config(implCls = PropertiesSettings::class) class AppConfig2 { }
- 无缓存的NoCacheKey
由于SmartKey会对value进行缓存,在多进程会存在问题。因此而生的NoCacheKey,保证读取的数据是实时的。
使用和SmartKey基本一致。
另外,在使用基于文件存储的Settings时,修改文件配置后,NoCacheKey可以监听文件变化,来载入最新配置。
var text: String by noCacheKey("defaultValue", key = "your_key")
- JsonSettings
使用json格式存储配置。
- PropertiesSettings
基于java PropertiesSettings持久化
可设置baseDir PropertiesSettings.baseDir = "..."
- FileSettings
使用文件存储。
可设置baseDir FileSettings.baseDir = "..."
其中 JsonSettings 和 PropertiesSettings 继承与 BaseSyncFileSetting,配置可随文件修改重新加载到内存。为达到此目的,你需要使用 NoCacheKey 来确保实时读取到的是修改后的配置
- 实现
com.russhwolf.settings.Settings接口
//必须存在构造函数(val configName:String) class MySettingsImpl(val configName:String) : Settings
- 使用自定义实现类
在配置类设置注解参数implCls:
@Config(implCls = MySettingsImpl::class) class AppConfig { }
allprojects {
repositories {
//...
maven { url 'https://jitpack.io' }
}
}- Kotlin
dependencies {
implementation "com.github.Vove7.SmartKey:smartkey:$lastest_version"
}- Android
dependencies {
implementation "com.github.Vove7.SmartKey:smartkey-android:$lastest_version"
}在开启混淆时,请注意添加规则以保证SmartKey正常工作。
- 由于实体类的持久化使用了Gson,请保证实体类字段名不被混淆,或使用注解@SerializedName
- 在没有指定key的config实例,例如 val a :Int by smaryKey(0),由于没有指定key,会默认使用变量名作为key,请保证变量名不被混淆(本人未验证kotlin编译混淆后,property name是否被改变)
- DynamicKey
this key can reset to 0 everyday:
val dk by synamicKey(0) { SimpleDateFormat("yyyy-MM-dd").format(Date()) + "_today_xxx_count" }
- ExpirableKey
- Kotlin
- 底层存储使用multiplatform-settings
- Gson