Android SharedPreferences跨运行无法保存数据问题排查
核心问题分析及解决
重复提交Editor修改
你的update_prefs()方法中同时调用了apply()和commit(),这两个方法都是提交SharedPreferences修改的接口,不能同时使用。apply()是异步写入磁盘,调用后Editor的修改已进入提交队列,此时再调用commit()会返回false,直接导致修改无法正确持久化到磁盘。
修复:只保留其中一个提交方法即可,推荐使用commit()(同步写入,可通过返回值确认提交结果)或apply()(异步写入,适合无需确认结果的场景),比如删除mEdit1.apply();这一行。lines变量一致性问题
如果lines不是全局成员变量,或者在调用update_prefs()前没有正确更新lines的内容,保存的就不是最新数据。比如readFile()里重新创建了ArrayList赋值给lines,但其他数据修改操作没有同步更新这个全局变量,就会导致保存旧数据甚至空数据。
修复:确保lines是全局成员变量,所有数据增删改操作都直接更新该变量,再调用update_prefs()执行保存。上下文实例错误
若调用PreferenceManager.getDefaultSharedPreferences(this)时的this不是全局上下文(比如临时创建的Context实例),会导致SharedPreferences指向不同的存储文件,跨运行自然读不到之前保存的数据。
修复:统一使用Application或Activity的全局上下文,比如在Activity中直接用this,在Fragment中用requireContext()。
优化后的update_prefs示例代码
private SharedPreferences.Editor update_prefs() { SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences.Editor mEdit1 = sp.edit(); int oldSize = sp.getInt("lines_size", 0); int newSize = lines.size(); // 清理冗余的旧数据键(当数据条数减少时) for(int i = newSize; i < oldSize; i++){ mEdit1.remove("Line_" + i); } mEdit1.putInt("lines_size", newSize); for(int i=0;i<newSize;i++) { mEdit1.putString("Line_" + i, lines.get(i)); } // 仅保留一个提交方法 mEdit1.commit(); return mEdit1; }
内容的提问来源于stack exchange,提问作者user13985829

