Android学习总结之MMKV(代替SharedPreferences)

一、引言:存储革命的必然性

在 Android 开发领域,SharedPreferences(SP)作为官方推荐的轻量级存储方案,曾是开发者的首选。然而,随着应用复杂度提升,SP 的缺陷逐渐暴露:ANR 风险、性能瓶颈、多进程灾难等问题频发。据统计,某头部应用因 SP 导致的 ANR 占比高达 18%,而微信团队通过自研 MMKV 实现了零 ANR 的突破。本文将深度解析 MMKV 如何解决 SP 的 "七宗罪",并揭秘其碾压级技术方案。

二、SP 的致命缺陷:开发者的 "七宗罪"

1. ANR 炸弹

  • 同步提交commit()直接阻塞主线程,磁盘写入耗时可达 100ms+
  • 异步陷阱apply()依赖QueuedWork,在 Activity 生命周期切换时强制等待
  • 加载死锁:首次调用getXXX()时若未加载完成,主线程会陷入无限等待

2. 性能黑洞

  • 全量更新:修改 1 个字段需重写整个 XML 文件
  • 内存双耗:内存常驻 + 冗余副本,导致内存占用翻倍

3. 多进程灾难

  • 文件锁冲突:跨进程读写时数据错乱概率高达 37%
  • 数据丢失风险:竞争条件下可能导致部分数据丢失

三、MMKV 的六大核心指标:碾压级技术突破

指标 1:性能 ——300 倍速度飞跃

// 写入性能对比(1000次操作)
SharedPreferences: 1200ms
SQLite: 800ms
MMKV: 7ms(300倍提升)
  • 内存映射(mmap):省去传统 IO 的 4 次数据拷贝
  • Protobuf 编码:体积缩小 45%,解析速度提升 5 倍
  • 增量更新:仅追加修改数据,避免全量重写

指标 2:稳定性 —— 微信 8 亿用户的考验

  • Crash 防护
    • 写时复制(Copy-on-Write)
    • CRC 校验 + 自动回滚机制
  • 空间自愈
    • 4KB 内存页动态扩展
    • 碎片整理算法提升空间利用率

指标 3:多进程 —— 打破 Android 的 "巴别塔"

// 多进程实现对比
// 传统方案(SP+ContentProvider)
getContentResolver().call(uri, ...);

// MMKV方案
MMKV kv = MMKV.mmkvWithID("inter_process_kv", MMKV.MULTI_PROCESS_MODE);
  • 跨进程锁(flock):原子操作保证数据一致性
  • Ashmem 匿名内存:敏感数据零落盘传输
  • 变更广播:通过 ContentProvider 实现状态同步

指标 4:数据安全 —— 比银行更严苛的加密

  • AES-CFB-128 加密:适配流式追加写入
  • 秘钥白盒保护:Native 层存储防反编译
  • HMAC 防篡改:每个数据包独立签名验证

指标 5:迁移成本 —— 一行代码无缝切换

// 迁移示例
MMKV.importFromSharedPreferences(oldSp);
oldSp.edit().clear().commit();
  • 支持保留原有 key 命名规范
  • 自动处理数据格式转换

指标 6:跨平台 —— 全场景覆盖

  • 统一 API:Android/iOS/macOS/Windows 同一接口
  • 混合开发支持:Flutter/React Native 通过 C++ 桥接

四、高频面试题深度解析

Q1:MMKV 如何解决 SP 的 ANR 问题?

  1. 异步无锁设计:mmap 直接写入内存,无需等待磁盘同步
  2. 队列优化:取消 QueuedWork 机制,任务提交独立线程池
  3. 无加载阻塞:初始化直接映射文件,避免异步加载死锁

Q2:mmap 会不会导致内存泄漏?

  • LRU 缓存淘汰:自动释放未使用实例的内存映射
  • 弱引用监控:通过 WeakReference 关联 Context

Q3:Protobuf 相比 XML 的优势?

维度 XML Protobuf
序列化速度 100ms / 万次 20ms / 万次
反序列化速度 120ms / 万次 25ms / 万次
数据体积 100KB 55KB

对比区别 

1、 SharedPreferences:

  • 一个轻量级的持久化存储类, 使用键值对的形式保存数据。

  • 可以存储的数据类型包括 Stringintbooleanfloat 和 long

  • 简单易用,但在高并发写操作下性能较差,会造成主线程阻塞问题。

2、 MMKV(微信开源):

  • 使用 mmap 内存映射文件,极大提高了读写性能。

  • 支持多进程读写。

  • 完全替代 SharedPreferences,有一致的 API 使用体验。

  • 提供分布式存储、数据加密等功能。

MMKV的优势

  • MMKV:

  • 基于 mmap,直接与内存交互,性能优越。

  • 高效的序列化和反序列化性能。

  • 支持多进程访问,不会造成数据竞争问题。

  • 提供 API 和 SharedPreferences 相似,容易上手。

  • 支持复杂类型的数据序列化。

  • 长时间表现稳定,微信等产品的实践已经验证其可靠性。

MMKV 使用示例
  1. 依赖配置:

implementation 'com.tencent:mmkv-static:1.2.10'

     2.初始化和使用:

import com.tencent.mmkv.MMKV

class MyApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        MMKV.initialize(this)
    }
}

fun saveData(key: String, value: String) {
    val kv = MMKV.defaultMMKV()
    kv.encode(key, value)
}

fun getData(key: String): String? {
    val kv = MMKV.defaultMMKV()
    return kv.decodeString(key)
}

感谢观看!!!

你可能感兴趣的:(android,学习)