標籤:
SharedPreferences內部工作原理:
1、調用getSharedPreferences();建立一個SharedPreferences對象,其中會先判斷是否存在對應xml檔案,如果發現存在則會有一個預先載入操作,這個操作是把xml檔案的內容通過I/O操作和XmlUitl解析後存入一個map對象中,所以我們調用SharedPreferences::getString();等get操作實際上是不會對檔案做I/O操作,而是直接存取剛剛的map集合的內容,這提高了效率,如果對應的xml不存在則重新建立一個對應的xml檔案。 
部分實現如下:
@Override    public SharedPreferences getSharedPreferences(String name, int mode) {        SharedPreferencesImpl sp;//...             sp = packagePrefs.get(name);            if (sp == null) {                File prefsFile = getSharedPrefsFile(name);                //該構造方法會調用startLoadFromDisk();把資料從硬碟載入到記憶體                sp = new SharedPreferencesImpl(prefsFile, mode);                packagePrefs.put(name, sp);                return sp;            }//...        return sp;    }
2、put寫操作:寫操作也有兩步,一是把資料先寫入記憶體中,即map集合,二是把資料寫入硬碟檔案中。這樣才能保證資料的完整性,寫操作有兩個提交的方式:
commit():安全執行緒,效能慢,一般來說在當前線程完成寫檔案操作 
apply():線程不安全,效能高,非同步處理IO操作,一定會把這個寫檔案操作放入一個SingleThreadExecutor線程池中處理
3、SharedPreferences在第一次建立後會一直維持一個Singleton,每次調用getSharedPreferences()都返回唯一的一個執行個體
        SharedPreferences a = getSharedPreferences("test",0);        SharedPreferences b = getSharedPreferences("test",0);        SharedPreferences c = getSharedPreferences("test",0);        Log.i(TAG, "result: "+(a==b)+","+(b==c));        //12-04 13:38:17.811 2287-2287/com.sunzxy.myapplication I/MainActivity: result: true,true
SharedPreferences使用封裝: 
由於SharedPreferences的key與value其實最終都是以String類型存在,所以可以這樣寫一個SharedPreferences工具類:
/** * Created by Sunzxyong on 15/12/4. */public class PerferenceManager {    private static final String PERF_NAME = "com.suznxyong.util.my_perf";    private static final int CURRENT_VERSION_CODE = 1;    private volatile static PerferenceManager instance;    private final SharedPreferences preferences;    private PerferenceManager(Context context) {        preferences = context.getSharedPreferences(PERF_NAME, Context.MODE_PRIVATE);        checkPrefVersion();    }    public static PerferenceManager getInstance(Context context) {        if (instance == null) {            synchronized (PerferenceManager.class) {                if (instance == null)                    instance = new PerferenceManager(context);            }        }        return instance;    }    public final void putValue(String key, String value) {        preferences.edit().putString(key, value).apply();    }    public final String getValue(String key) {        checkIsLegal(key);        return preferences.getString(key, "");    }    public final void deleteValue(String key) {        checkIsLegal(key);        preferences.edit().remove(key).apply();    }    public final void clear() {        preferences.edit().clear().apply();    }    private void checkIsLegal(String key) {        if (TextUtils.isEmpty(key))            throw new IllegalArgumentException("This parameter is illegal,key : " + key);    }    private void checkPrefVersion() {        final int oldVersion = preferences.getInt(PERF_NAME, 0);        if (oldVersion < CURRENT_VERSION_CODE) {            preferences.edit()                    .clear()                    .putInt(PERF_NAME, CURRENT_VERSION_CODE).apply();        }    }}
由於應用版本升級時並不會刪除SharedPreferences檔案,所以可以加個版本判斷,來進行一些資料更新,從上面看來,由於每一次調用getSharedPreferences()都會有IO操作,當內容比較多時,那麼就不適宜在Application的onCreate中進行SharedPreferences檔案初始化了,最好的辦法是開個子線程去完成它的建立和資料的預先載入!!!
 
Android之SharedPreferences內部原理淺析