Coder Social home page Coder Social logo

krosxx / smartkey Goto Github PK

View Code? Open in Web Editor NEW
17.0 2.0 2.0 388 KB

⚙ 利用Kotlin委托实现优雅地持久化存储配置。

Kotlin 75.66% Java 24.34%
kotlin android config-management configuration key-value smartkey android-library kotlin-library

smartkey's Introduction

SmartKey

利用Kotlin委托实现优雅地持久化存储应用配置。

  1. 支持纯Kotlin项目
  2. 支持Android项目
  3. 支持自定义持久化实现
  4. 空安全
  5. 配置动态监听

基本使用

初始化

这里可以使用注解 @Config("app_config", implCls = ...) 配置存储文件名,多个配置类可分文件存储。
安卓项目可以无需指明implCls,自动使用 SharedPreference 做存储;使用数据库需要适配,参考: 自定义持久化实现

  1. 定义配置类
//注解非必须,不加注解,会使用默认配置路径,和默认存储实现
@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
)
  1. 此时你可以像这样使用
//获取存储值
val value = AppConfig.text
val n = AppConfig.number 

//实时存储
AppConfig.text = "setValue"
AppConfig.number = 0

//存储登录用户数据
val user = UserInfo("new_user", "[email protected]", 0)
AppConfig.userInfo = user

//注意修改实体中的属性无法触发持久化操作
user.name = "hello"
//需要赋值操作触发
AppConfig.userInfo = user

//操作 实时存储 无需显式赋值;需要注意避免循环 add, 可以使用addAll
AppConfig.modelList.add(ListModel("string", 1))
//set map 操作同 List 实时存储
  1. 配置类附加功能

继承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]

demo

见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 = "..."

其中 JsonSettingsPropertiesSettings 继承与 BaseSyncFileSetting,配置可随文件修改重新加载到内存。为达到此目的,你需要使用 NoCacheKey 来确保实时读取到的是修改后的配置

自定义持久化实现

  1. 实现com.russhwolf.settings.Settings接口
//必须存在构造函数(val configName:String)

class MySettingsImpl(val configName:String) : Settings
  1. 使用自定义实现类

在配置类设置注解参数implCls

@Config(implCls = MySettingsImpl::class)
class AppConfig {

}

引入SmartKey

Step 1. Add it in your root build.gradle at the end of repositories:
allprojects {
    repositories {
        //...
        maven { url 'https://jitpack.io' }
    }
}
Step 2. Add the dependency
  • Kotlin
dependencies {
    implementation "com.github.Vove7.SmartKey:smartkey:$lastest_version"
}
  • Android
dependencies {
    implementation "com.github.Vove7.SmartKey:smartkey-android:$lastest_version"
}

lastest_version :

注意事项

在开启混淆时,请注意添加规则以保证SmartKey正常工作。

  1. 由于实体类的持久化使用了Gson,请保证实体类字段名不被混淆,或使用注解@SerializedName
  2. 在没有指定key的config实例,例如 val a :Int by smaryKey(0),由于没有指定key,会默认使用变量名作为key,请保证变量名不被混淆(本人未验证kotlin编译混淆后,property name是否被改变)

TODO

  • DynamicKey

this key can reset to 0 everyday:

val dk by synamicKey(0) {  
    SimpleDateFormat("yyyy-MM-dd").format(Date()) + "_today_xxx_count"
}
  • ExpirableKey

Thanks

smartkey's People

Contributors

krosxx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

bcsl panyy

smartkey's Issues

Boolean类型更改无效

Boolean类型更改无效,别的类型没事
1、var haveMask:Boolean by smartKey(true)
2、AppConfig.INSTANCE.setHaveMask(false);
杀掉进程重启,发现还是true

混淆

开启混淆的情况下需要确保使用自定义 key 或者把 config 类的字段 keep 住才行,这个应该写到文档

配合 PreferenceFragment 使用

  1. 下载 SmartKeyDataStore.kt 到你的项目

  2. 设置 preferenceManager.preferenceDataStore = SmartKeyDataStore(YourConfig)

   class SettingsFragment : PreferenceFragmentCompat() {
        override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
            preferenceManager.preferenceDataStore = SmartKeyDataStore(AppConfig)
            setPreferencesFromResource(R.xml.root_preferences, rootKey)
        }
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.