[Android] 使用 Delegate 封裝 MMKV
4 min readJan 26, 2020
MMKV 是由騰訊公司開源的一款基於 mmap 的高性能鍵值(Key/Value)儲存框架,底層的序列化/反序列化是透過 protobuf 協定來實現。
若寫入一個隨機的 Integer 1000次,速度跟一般 SharedPreferences 可差到將近 100 倍。
其實可以把它當成高效版的 SharedPreferences ,其類別實作了 SharedPreferences 的 interface,而且還提供 importFromSharedPreferences() 方法能直接無痛從 SharedPreferences 遷移到 MMKV 。
引入依賴
implementation 'com.tencent:mmkv-static:{MMKV_VERSION}'
封裝 Delegate 邏輯
Delegate 主要是將要實作的內容,透過另一個類別來完成,這邊我們覆寫了 getValue
及 setValue
方法來處理 MMKV 取值及賦值的邏輯。
class MMKVDelegate<T>(
private val mmkv: MMKV,
private val key: String,
private val defValue: T
) {
@Suppress("UNCHECKED_CAST")
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return mmkv.run {
when (defValue) {
is String -> getString(key, defValue)
is Boolean -> getBoolean(key, defValue)
is Long -> getLong(key, defValue)
is Int -> getInt(key, defValue)
is Float -> getFloat(key, defValue)
else -> Unit
}
} as T
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
mmkv.run {
when (value) {
is String -> putString(key, value)
is Boolean -> putBoolean(key, value)
is Long -> putLong(key, value)
is Int -> putInt(key, value)
is Float -> putFloat(key, value)
else -> Unit
}
}
}
}
撰寫要儲存的鍵值
提供全局的 application context 來初始化 MMKV,並透過 by lazy 的方式來延遲加載 property,封裝好處在於不需要把 KEY 散落在各處,能夠有效地避免使用到錯誤的 Key ,並且對於預設值也能有一致性。
class LocalData(appContext: Context) {
private val mmkv = MMKV.initialize(appContext).run { MMKV.defaultMMKV() }
var username: String by MMKVDelegate(mmkv, "key_username", "")
var isLogin: Boolean by MMKVDelegate(mmkv, "key_is_login", false)
}
基礎使用
在要讀寫的地方呼叫剛剛封裝好的 LocalData 類別,基礎使用就是這麼的簡單,完整 Demo 可以到我的 Github 查看!
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val localData = LocalData(applicationContext)
localData.username = "Joseph Wang"
localData.isLogin = true
Log.d("MMKV", "username: ${localData.username}")
Log.d("MMKV", "isLogin: ${localData.isLogin}")
// Output
// D/MMKV: username: Joseph Wang
// D/MMKV: isLogin: true
}
}