回天乏术,SharedPreferences 已经彻底告别了这个时代?
Posted BUGgogogo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回天乏术,SharedPreferences 已经彻底告别了这个时代?相关的知识,希望对你有一定的参考价值。
数据持久化需求
在android开发过程中,我们避不开持久化key-value数据需求。
目前实现Android本地数据持久化有以下三种最常用的形式:
- 文件存储数据
- SQLite数据库存储数据
- 使用SharedPreferences存储数据
其中,SharedPreferences(以下简称 SP) 是Android系统提供的一种轻量级的Key-Value数据存取方式,使用起来非常方便。
SharedPreferences的问题
在初始化 SP 的时候,会将整个文件内容加载内存中,因此会带来以下问题:
- 初始化使用子线程进行IO读取并完成XML解析,而其他所有操作(
getXXX
、edit
)都需要等待初始化完成,可能会导致主线程阻塞 - SharedPreference 不能保证类型安全
- SharedPreference 加载的数据会一直留在内存中,浪费内存
- apply() 方法虽然是异步的,但因为设计问题,仍然可能会导致程序发生 ANR
- apply() 方法无法获取到操作成功或者失败的结果
- 没有事务性API,无法保证数据一致性(内存与磁盘数据不一致,数据丢失)
- …
解决SP 问题
实际上SP在Android中是一个接口,而我们在ContextWrapper(Application、Service、Activity)中获得的SP对象实例为:android.app.SharedPreferenceImpl
,所以第一种解决方案就是自己实现SP替换掉ContextWrapper中的getSharedPreference返回的SharedPreferenceImpl实现,从而解决SP的ANR问题。
而腾讯微信由于特殊文字引起系统的 crash的问题,需要一个高性能的通用 key-value 存储组件,因此研发了一个MemoryMappedKV(简称MMKV )工具,在腾讯内部开源半年,得到公司内部团队的广泛应用和一致好评 ,并将其在2018年开源在Github中。
MMKV在Android端实现了SharedPreference接口,将 MMKV 和 SharedPreferences、SQLite 进行对比, 重复读写操作 1k 次,结果如下:
显而易见的,相比于 SP 和 SQLite ,MMKV 在性能上都有极大的优势。
MMKV的优势显而易见:
- 从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证
- 底层序列化/反序列化使用 protobuf
- 使用零拷贝技术——mmap内存映射完成数据持久化
- 支持SharedPreferences迁移到mmkv
- 性能远超SharedPreferences
- 支持多进程的读写
- 提供Android / macOS / Win32 / POSIX 多平台 的实现
- ……
而SharedPreferences 实惨(拉跨)!屋漏偏逢连夜雨,亲妈都开始嫌弃他了。
来自亲妈的告别
继腾讯开源类似功能的MMKV之后,Google官方新增加了一个新 Jetpack 的成员 DataStore,目的就是用来替换饱受诟病的 SharedPreferences。
DataStore 是基于 Flow 实现的一个库,一种新的数据存储方案,它提供了两种实现方式:
-
Proto DataStore:存储类的对象(typed objects ),通过 protocol buffers 将对象序列化存储在本地
-
Preferences DataStore:以键值对的形式存储在本地和 SharedPreferences 类似
但是
我们仅仅只是了解这些就够了吗?下面这些问题你都明白吗?
- SharedPreferences是如何保证线程安全的,内部的实现用到了哪些锁?
- 为什么SharedPreferences会有这些缺陷,这些缺陷如何改进?
- SharedPrefernces到底有哪些问题的存在?
- MMKV和DataStore又是如何解决这些问题的呢?
- ……
我们的学习不仅仅只是掌握其API的调用,更希望能够通过了解SP的实现原理,从而避免我们自实现的代码中出现类似问题。同时掌握MMKV与DataStore原理,学习其优秀的设计,将其中运用的知识点能够引入到项目的各种需求中解决问题。
以上问题都收录在《超全App性能优化知识技能手册》里面!有需要的朋友可以去我的【私人号】获取,或者是看我的Git点击可看。
以上是关于回天乏术,SharedPreferences 已经彻底告别了这个时代?的主要内容,如果未能解决你的问题,请参考以下文章
反思|官方也无力回天?Android SharedPreferences的设计与实现