看完这篇文章你还敢用SharedPreference吗?

1. 前言

作为 Android 入门时学习的第一个简单的存储方案,SharedPreference 是每个初学者绕不开的知识点。它使用简单,常常用来存储键值对数据,比如一些配置信息。但是如果你把它作为主要存储方案,存储大量数据时,请慎用。因为它有着令人 震惊的性能缺陷。

2. SharedPreference 的使用回顾

2.1 写数据

先获取 SharedPreferences 对象。

// 文件名:my_config
// 模式:MODE_PRIVATE 只有本应用能访问
SharedPreferences sp = getSharedPreferences("my_config", Context.MODE_PRIVATE);
  • 方式一:异步写数据 apply

apply 后不写入磁盘,而是择机由系统调度,使用子线程写入。

SharedPreferences.Editor editor = sp.edit();

editor.putString("username", "zhangsan");
editor.putInt("age", 20);
editor.putBoolean("is_login", true);
editor.putFloat("score", 95.5f);
editor.putLong("last_time", System.currentTimeMillis());

// 异步提交
editor.apply();
  • 方式二:同步写数据 commit

同步写的优点是有返回值,缺点是阻塞当前线程。

boolean success = editor.commit();
if (success) {
    // 写入磁盘成功
}

2.2 读数据

读取数据很简单,根据key获取value,可以根据需要读取不同类型的值。

String username = sp.getString("username", "默认名字");
int age = sp.getInt("age", 0);
boolean isLogin = sp.getBoolean("is_login", false);
float score = sp.getFloat("score", 0f);
long lastTime = sp.getLong("last_time", 0L);

3. SharedPreference 的缺陷

3.1 全量读写XML文件

SharedPreference 存储数据的原理是将数据写入 XML 文件。
读写文件本来就是比较耗费性能的事,你敢想象吗?每次新增或修改一个键值对时,它竟然要全量读写底层的XML文件! 也就是说,即使你只修改其中一个值,它也会把整个XML文件读到内存,然后修改,再全部写回XML文件!
假如你的XML文件里有一万条数据,天呐!工作量是多么大,难怪APP会卡了吧。

3.2 页面暂停强制阻塞写文件

有些朋友可能注意到 SharedPreference 为了提高性能,在更新数据时不阻塞UI,设计了 apply 的提交方式。它不会立刻写入文件,而是择机异步写入,从而避免大量 IO 操作阻塞主线程。

但是它还有一个逆天的设计:在页面生命周期 Pause 时,强制阻塞 UI 线程,进行 SharedPreference 的文件写入。

这是为了防止数据丢失的策略,但就是这个策略会导致在页面跳转时,如果你有大量的 SharedPreference 等待写入,就会跳转卡顿!

3.3 多线程不安全

还有一个无法解决的问题,SharedPreference 的文件读写是没有锁保护的

也就意味着多线程或者多进程下,都可以读写文件,你拿到的数据可能不是最新的,也就是所谓的脏数据。你使用apply 写入的时候,如果别人也用了 apply 写入,那么可能你的数据被别人覆盖。在大型项目中太危险了啊!

4. 总结

SharedPreference 是Android开发初学者必须了解的一个简单的存储工具,但随着学习的深入,我们要知道它的原理和优缺点。在复杂项目中,它的缺点已经不容忽视。主要包括:

  • 全量读写XML文件
  • 生命周期阻塞写入
  • 多线程不安全

那么问题来了,我们不用它,该用什么呢?我们下篇文章接着讲:替代 SharedPreference 的最佳键值对存储方案:MMKV

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子林Android

感谢老板,老板大气!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值