Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之SharedPreferences內部原理淺析

Android之SharedPreferences內部原理淺析

編輯:關於Android編程

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文件初始化了,最好的辦法是開個子線程去完成它的創建和數據的預加載!!!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved