利用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 classListModel(vals:String, vala:Int)
//实体类data classUserInfo(
varname:String,
varemail:String,
varage: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, 可以使用addAllAppConfig.modelList.add(ListModel("string", 1))
//set map 操作同 List 实时存储- 配置类附加功能
继承BaseConfig拥有配置类基础操作
object AppConfig : BaseConfig {
//...
}// 清空此配置所有keyAppConfig.clear()
// 直接存储keyAppConfig["key"] =1//key, valueAppConfig["text"] ="abc"//key, value// 加密储存(目前只支持String及实体类型加密)AppConfig["key", true] ="value""key"inAppConfig// is contains keyAppConfig-="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"]
// orval user =AppConfig.get<UserInfo?>("userInfo")
//获取加密内容val user:UserInfo?=AppConfig["userInfo", true]
见app目录
- 你可以指定变量对应存储的key:
object AppConfig2 : BaseConfig { //指定key //import cn.vove7.smartkey.smartKeyvar text:String by smartKey("defaultValue", key ="your_key")
var textWithKey:String by smartKey("aaa", key="text_key")
//安卓项目可通过resId指定keyId//import cn.vove7.smartkey.android.smartKeyvar textAndroid:String by smartKey("defaultValue", keyId =R.string.key)
}- key 动态绑定
print(AppConfig2.textWithKey) //aaaAppConfig2["text_key"] ="bbb"print(AppConfig2.textWithKey) //bbb- 选择是否加密数据:
//使用encrypt来声明加密存储数据var userInfo:UserInfo? by smartKey(null, encrypt =true)
- 为每个配置类设置存储实现
不指定
implCls时, 默认实现为JsonSettings
@Config(implCls =FileSettings::class)
classAppConfig1 {
}
@Config(implCls =PropertiesSettings::class)
classAppConfig2 {
}- 无缓存的NoCacheKey
由于SmartKey会对value进行缓存,在多进程会存在问题。因此而生的NoCacheKey,保证读取的数据是实时的。
使用和SmartKey基本一致。
另外,在使用基于文件存储的Settings时,修改文件配置后,NoCacheKey可以监听文件变化,来载入最新配置。
var text:String by noCacheKey("defaultValue", key ="your_key")- JsonSettings
使用json格式存储配置。
- PropertiesSettings
基于java PropertiesSettings持久化
可设置baseDirPropertiesSettings.baseDir = "..."
- FileSettings
使用文件存储。
可设置baseDirFileSettings.baseDir = "..."
其中 JsonSettings 和 PropertiesSettings 继承与 BaseSyncFileSetting,配置可随文件修改重新加载到内存。为达到此目的,你需要使用 NoCacheKey 来确保实时读取到的是修改后的配置
- 实现
com.russhwolf.settings.Settings接口
//必须存在构造函数(val configName:String)classMySettingsImpl(valconfigName:String) : Settings- 使用自定义实现类
在配置类设置注解参数implCls:
@Config(implCls =MySettingsImpl::class)
classAppConfig {
}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
