1.前言
在10.0的系统rom定制化开发中,在用sharedpereference保存数据的时候,有时候会出现在断电的情况下数据会丢失的功能, 接下来分析下数据保存流程,然后解决问题
2.sharedpereference保存数据断开电源数据丢失问题解决的核心类
frameworks/base/core/java/android/content/SharedPreferences.java
frameworks/base/core/java/android/app/SharedPreferencesImpl.java
3.sharedpereference保存数据断开电源数据丢失问题解决的核心功能分析和实现
SharedPreferences是Android平台上一个轻量级的存储类,当程序中有一些少量数据需要持久化存储时,可以使用SharedPreferences进行存储。 一、SharedPreferences的数据操作 1、将数据存入SharedPreferences中 使用SharedPreferences存储数据时,首先需要调用getSharedPreferences()方法获取SharedPreferences的实例对象。由于该对象本身只能获取数据,不能对数据进行存储和修改,所以需要调用SharedPreferences的edit()方法获取到可编辑的Editor对象,最后通过Editor对象的putXxx()方法存储数据 SharedPreferences)是Android上的一个轻量级存储工具,存储结构是类似map的key—value键值对形式。它主要用于保存app的基础设置
3.1 SharedPreferences.java的相关功能分析和实现
1、SharedPreferences 基本介绍 SharedPreferences 是 Android 的一个轻量级存储工具,它采用 key - value 的键值对方式进行存储 它允许保存和读取应用中的基本数据类型,例如,String、int、float、boolean 等 保存共享参数键值对信息的文件路径为:/data/data/【应用包名】/shared_prefs/【SharedPreferences 文件名】.xml
public interface SharedPreferences {/*** Interface definition for a callback to be invoked when a shared* preference is changed.*/public interface OnSharedPreferenceChangeListener {/*** Called when a shared preference is changed, added, or removed. This* may be called even if a preference is set to its existing value.** <p>This callback will be run on your main thread.**/void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);}/*public interface OnSharedPreferenceChangeListener {/*** Called when a shared preference is changed, added, or removed. This* may be called even if a preference is set to its existing value.** <p>This callback will be run on your main thread.** <p><em>Note: This callback will not be triggered when preferences are cleared via* {@link Editor#clear()}.</em>** @param sharedPreferences The {@link SharedPreferences} that received* the change.* @param key The key of the preference that was changed, added, or* removed.*/void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);}*//*** Interface used for modifying values in a {@link SharedPreferences}* object. All changes you make in an editor are batched, and not copied* back to the original {@link SharedPreferences} until you call {@link #commit}* or {@link #apply}*/public interface Editor {/*** Set a String value in the preferences editor, to be written back once* {@link #commit} or {@link #apply} are called.** @param key The name of the preference to modify.* @param value The new value for the preference. Passing {@code null}* for this argument is equivalent to calling {@link #remove(String)} with* this key.** @return Returns a reference to the same Editor object, so you can* chain put calls together.*/Editor putString(String key, @Nullable String value);/*** Set a set of String values in the preferences editor, to be written* back once {@link #commit} or {@link #apply} is called.** @param key The name of the preference to modify.* @param values The set of new values for the preference. Passing {@code null}* for this argument is equivalent to calling {@link #remove(String)} with* this key.* @return Returns a reference to the same Editor object, so you can* chain put calls together.*/Editor putStringSet(String key, @Nullable Set<String> values);Editor putInt(String key, int value);Editor putLong(String key, long value);Editor putFloat(String key, float value);Editor putBoolean(String key, boolean value);Editor remove(String key);Editor clear();boolean commit();void apply();}
.....
}
在实现sharedpereference保存数据断开电源数据丢失问题解决的核心功能中,可以看到 SharedPreferences是个接口,实现了相关保存数据的方法,具体保存数据是在Editor 的commit()和apply()方法中,
//add core start//do syncpublic static void fileSync() {new Thread(new Runnable() {@Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//syncRuntime runtime = Runtime.getRuntime();try {runtime.exec("sync");} catch (IOException e) {e.printStackTrace();}}}).start();}
//add core end@Overridepublic Editor clear() {synchronized (mEditorLock) {mClear = true;return this;}}@Overridepublic void apply() {final long startTime = System.currentTimeMillis();final MemoryCommitResult mcr = commitToMemory();final Runnable awaitCommit = new Runnable() {@Overridepublic void run() {try {mcr.writtenToDiskLatch.await();} catch (InterruptedException ignored) {}if (DEBUG && mcr.wasWritten) {Log.d(TAG, mFile.getName() + ":" + mcr.memoryStateGeneration+ " applied after " + (System.currentTimeMillis() - startTime)+ " ms");}}};QueuedWork.addFinisher(awaitCommit);Runnable postWriteRunnable = new Runnable() {@Overridepublic void run() {awaitCommit.run();QueuedWork.removeFinisher(awaitCommit);}};SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);// Okay to notify the listeners before it's hit disk// because the listeners should always get the same// SharedPreferences instance back, which has the// changes reflected in memory.notifyListeners(mcr);
+ fileSync();}@Overridepublic boolean commit() {long startTime = 0;if (DEBUG) {startTime = System.currentTimeMillis();}MemoryCommitResult mcr = commitToMemory();SharedPreferencesImpl.this.enqueueDiskWrite(mcr, null /* sync write on this thread okay */);try {mcr.writtenToDiskLatch.await();} catch (InterruptedException e) {return false;} finally {if (DEBUG) {Log.d(TAG, mFile.getName() + ":" + mcr.memoryStateGeneration+ " committed after " + (System.currentTimeMillis() - startTime)+ " ms");}}notifyListeners(mcr);
+ fileSync();return mcr.writeToDiskResult;}
在实现sharedpereference保存数据断开电源数据丢失问题解决的核心功能中,在SharedPreferencesImpl.java中 具体实现保存数据的功能,所以在EditorImpl的commit()和apply()方法中,添加sync的相关方法来同步数据到 磁盘中来实现数据的保存