今日博文推荐一款开源库:MMKV-Kotlin, 从名字就能看出来这是基于腾讯开源的mmkv项目进行进一步封装的。
下面我们看一下两者的特点及有什么区别。
SharedPreferences
为什么首先要提一下Android中常用的sp呢?因为在Android开发中这是轻量的Key-value类型的存储方案,主要用于存储一些轻量数据,比如偏好,配置等,是一个xml文件。
SP存在问题:
1.性能问题,导致ANR
SharedPreferences对应的commit或者apply方法,区别在于同步写入和异步写入以及是否需要返回值,在不需要返回值的情况下,apply可以提高性能。注意apply会将数据原子提交到内存,然后异步提交到硬件磁盘,commit是同步提交到磁盘,commit对多并发场景不友好。
在apply()方法中,首先会创建一个等待锁,根据源码版本的不同,最终更新文件的任务会交给QueuedWork.singleThreadExecutor()单个线程或者HandlerThread去执行,当文件更新完毕后会释放锁。
但当Activity.onStop()以及Service处理onStop等相关方法时,则会执行 QueuedWork.waitToFinish()等待所有的等待锁释放,因此如果SharedPreferences一直没有完成更新任务,有可能会导致卡在主线程,最终超时导致ANR。
2.非进程安全
SharedPreferences是线程安全的,这个毋庸置疑,你看方法内大量的synchronized就是用来保障数据正确性的。
但它不是进程安全的,同一个文件,A进程正在读取,B进程正在写,B进程加载SP时会将备份文件重命名为原文件名,A进程读取,读取到的数据只能是之前原文件写入到内存中的文件,B进程写入的内容其他在操作的进程也无法获取。
这里不推荐大家在多进程中使用sp.
腾讯:MMKV
MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。
原理
内存准备
通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。
数据组织
数据序列化方面我们选用 protobuf 协议,pb 在性能和空间占用上都有不错的表现。
写入优化
考虑到主要使用场景是频繁地进行写入更新,我们需要有增量更新的能力。我们考虑将增量 kv 对象序列化后,append 到内存末尾。
空间增长
使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。
项目地址
github: https://github.com/Tencent/MMKV
携程开源Kotlin版本:mmkv-kotlin 背景
相较于 SharedPreferences 与 NSUserDefaults,MMKV 拥有更强大的性能;相较于 Jetpack Datastore,MMKV 同时支持多个平台,双端业务逻辑一致性会更好;此外,MMKV 的优势还包括:支持多进程访问、进程被突然杀死时存储依然可以生效等。因此,携程机票移动端研发团队决定基于 MMKV 二次开发,使 MMKV 支持 Kotlin Multiplatform 技术栈。
MMKV-Kotlin 因此应运而生,它拥有极为便捷的集成方式,与 MMKV 高度相似的 API 等诸多特点。对于有 MMKV 使用经验的原移动端开发人员来说,学习迁移成本很低。在经过了大半年的线上实验证明了其稳定性与功能的完整性后,携程机票研发团队决定将其开源,为 Kotlin Multiplatform 开源生态添砖加瓦。
项目地址
github: https://github.com/ctripcorp/mmkv-kotlin
--- End ---
点击关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.