Android开发-存储框架技术总结
一、MMKV模块
MMKV 之所以成为 SharedPreferences 的优质替代方案,主要在于其在多个维度的显著优势。首先,在性能上,MMKV 底层技术采用了内存映射(mmap)技术,将文件直接映射到内存,使得数据读写操作直接在内存中完成,并由操作系统异步刷盘,从而彻底避免了传统 SharedPreferences 同步 I/O 带来的主线程阻塞问题。这使得 MMKV 的读写速度比 SharedPreferences 快数百倍,有效解决了应用卡顿和 ANR(应用无响应)的痛点。
其次,在多进程环境下,MMKV 提供了可靠的数据一致性保障。它通过 Linux 内核级的 flock()
原子锁机制来管理读写,有效避免了多进程并发操作可能导致的数据错乱。同时,MMKV 利用匿名共享内存传输数据,实现了无需序列化的跨进程通信,大大提升了数据同步的效率和安全性。
此外,MMKV 在数据格式和内存管理上也进行了深度优化。它使用 Protobuf 二进制编码,不仅数据体积更小,序列化与反序列化速度也更快,且静态类型系统从编译期就确保了类型安全。在内存管理方面,MMKV 内置了 LRU 缓存机制,能够智能地释放不常用的内存,并使用弱引用避免了 Activity 内存泄漏,确保了应用运行的稳定性。
最后,MMKV 在易用性和功能扩展方面也表现出色。它提供了便捷的一键迁移工具,帮助开发者平滑地从 SharedPreferences 切换。同时,内置的 AES 加密功能、事务性批量写入以及对 Parcelable 对象的直接支持,都极大地简化了开发工作,并满足了高安全性与高效率的开发需求。总而言之,MMKV 通过底层技术的革新,全面超越了 SharedPreferences,成为现代 Android 应用数据存储的理想选择。
二、UniKV模块
UniKV 是一种基于 SQLite 的键值对存储方案,它旨在解决传统 SharedPreferences 在数据一致性和多进程并发方面的痛点。UniKV 的核心优势在于它充分利用了 SQLite 数据库的强大能力,将所有数据存储在一个 SQLite 表中。这使得 UniKV 能够获得 ACID 事务支持,确保即使在应用崩溃或多进程同时写入的极端情况下,数据也能保持完整和一致,有效避免了数据损坏和错乱。
在具体实现上,UniKV 借鉴了 SQLite 的文件锁机制来保障多进程安全,确保任何时候都只有一个进程能对数据库进行写入操作,从而杜绝了数据竞争问题。同时,为了提升性能,UniKV 在内存中引入了 LRU 缓存,优先从内存中读取数据,只有在缓存未命中时才访问磁盘,并通过批量提交事务来减少写入次数,实现了在保证高可靠性的同时兼顾了读写效率
三、内存映射问题
在进程间使用共享内存进行通信时,数据从进程A传递到进程B通常只发生一次数据拷贝。这是因为共享内存的实现机制是,操作系统将同一块物理内存区域映射到两个进程的虚拟地址空间,进程A将数据写入这块共享内存,进程B可以直接从这块物理内存读取,避免了数据在内核和用户空间之间来回复制。
这种内存映射机制是借助操作系统的虚拟内存管理实现的,通过页表将虚拟地址映射到物理地址,从而允许不同的进程访问同一块物理内存。从Android工程师的角度看,共享内存通信主要通过Binder机制在底层实现,常用的机制是Ashmem
(Android Shared Memory),它是一种针对Android优化的匿名共享内存,常用于MediaCodec
等框架中,用于高效传递大块数据,以减少不必要的数据拷贝。
Ashmem 的工作流程可以概括为:一个进程(例如进程 A)首先在内核中创建一块 Ashmem 共享内存区域,并获得一个特殊的文件描述符。然后,进程 A 将需要传输的数据写入这块共享内存。接下来,它通过 Binder 机制,将这个文件描述符作为 IPC 参数传递给另一个进程(进程 B)。进程 B 接收到文件描述符后,调用 mmap()
系统调用将这块共享内存映射到自己的虚拟地址空间。至此,两个进程都拥有了对同一块物理内存的直接访问权限,从而实现了高效的数据共享,完全避免了在进程间进行大块数据的拷贝。