Android 常用代碼整理:配置文件工具類(SPUtil)

說明:大部分內容都是參考別的文章,這裏做整理是爲了以後的編程有實用的模板,可以即需即用。

import android.content.Context;
import android.content.SharedPreferences;

import java.util.ArrayList;
import java.util.List;

public class SPUtil {

    private static final String PREFERENCES_FILE_NAME = "com.xq.shared_preferences";
    private static SharedPreferences mSharedPreferences = MyApplication.getInstance().getSharedPreferences(PREFERENCES_FILE_NAME, Context.MODE_PRIVATE);
    private static SharedPreferences.Editor mEditor = mSharedPreferences.edit();

    /**
     * 保存一個 String 類型的值
     */
    public static boolean putString(String key, String value) {
        return mEditor.putString(key, value).commit();
    }

    /**
     * 獲取 String 的 value
     */
    public static String getString(String key, String defValue) {
        return mSharedPreferences.getString(key, defValue);
    }

    /**
     * 保存一個 Boolean 類型的值
     */
    public static boolean putBoolean(String key, Boolean value) {
        return mEditor.putBoolean(key, value).commit();
    }

    /**
     * 獲取 boolean 的 value
     */
    public static boolean getBoolean(String key, Boolean defValue) {
        return mSharedPreferences.getBoolean(key, defValue);
    }

    /**
     * 保存一個 int 類型的值
     */
    public static boolean putInt(String key, int value) {
        return mEditor.putInt(key, value).commit();
    }

    /**
     * 獲取 int 的 value
     */
    public static int getInt(String key, int defValue) {
        return mSharedPreferences.getInt(key, defValue);
    }

    /**
     * 保存一個 float 類型的值
     */
    public static boolean putFloat(String key, float value) {
        return mEditor.putFloat(key, value).commit();
    }

    /**
     * 獲取 float 的 value
     */
    public static float getFloat(String key, Float defValue) {
        return mSharedPreferences.getFloat(key, defValue);
    }

    /**
     * 保存一個 long 類型的值
     */
    public static boolean putLong(String key, long value) {
        return mEditor.putLong(key, value).commit();
    }

    /**
     * 獲取 long 的 value
     */
    public static long getLong(String key, long defValue) {
        return mSharedPreferences.getLong(key, defValue);
    }

    /**
     * 存儲 List<String>
     */
    public static void putStrListValue(String key, List<String> strList) {
        if (null == strList) {
            return;
        }
        // 保存之前先清理已經存在的數據,保證數據的唯一性
        removeStrList(key);
        int size = strList.size();
        putInt(key + "size", size);
        for (int i = 0; i < size; i++) {
            putString(key + i, strList.get(i));
        }
    }

    /**
     * 獲取 List<String>
     */
    public static List<String> getStrListValue(String key) {
        List<String> strList = new ArrayList<String>();
        int size = getInt(key + "size", 0);
        for (int i = 0; i < size; i++) {
            strList.add(getString(key + i, null));
        }
        return strList;
    }

    /**
     * 清空 List<String>
     */
    public static void removeStrList(String key) {
        int size = getInt(key + "size", 0);
        if (0 == size) {
            return;
        }
        remove(key + "size");
        for (int i = 0; i < size; i++) {
            remove(key + i);
        }
    }

    /**
     * 清空對應 key 數據
     */
    public static boolean remove(String key) {
        return mEditor.remove(key).commit();
    }

}
public class MyApplication extends Application {

    private static MyApplication mMyApplication;

    public static MyApplication getInstance() {
        return mMyApplication;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mMyApplication = this;
    }
}

一、概述

1、SharedPreferences 是 Android中 常用的數據存儲方式,SharedPreferences 採用 key-value(鍵值對)形式,主要用於輕量級的數據存儲,尤其適合保存應用的配置參數,但不建議使用 SharedPreferences 來存儲大規模的數據,可能會降低性能。如果一個 SharedPreferences 對應的 xml 文件很大的話,在初始化時會把這個文件的所有數據都加載到內存中,這樣就會佔用大量的內存,有時我們只是想讀取某個 xml 文件中一個 key 的 value,結果它把整個文件都加載進來了,如果必要的話需要進行相關優化處理(比如在子線程中加載)。
2、SharedPreferences 採用 xml 文件格式來保存數據,文件所在目錄位於 /data/data/<package_name>/shares_prefs。
3、PreferencesMode:

  • Context.MODE_PRIVETE:指定該 SharedPreferences 數據只能被本應用程序讀寫。
  • Context.MODE_APPEND:檢查文件是否存在,存在就往文件追加內容,否則就創建新文件。
  • Context.MODE_WORLD_READABLE:指定該 SharedPreferences 數據能被其他應用程序讀,但不能寫。
  • Context.MODE_WORLD_WRITEABLE:指定該 SharedPreferences 數據能被其他應用程序讀寫。

二、注意事項

1、getSharedPreferences() 是從 ContextImpl.sSharedPrefsCache 獲取唯一的 SPI 對象。對於一個相同的SharedPreferences name,獲取到的都是同一個 SharedPreferences 對象,它其實是一個 SharedPreferencesImpl 對象。
2、每次 edit 都會創建一個新的 EditorImpl 對象。最好不要連續多次 edit(),應該獲取一次 edit(),然後多次執行 putXxx(),最後統一提交,減少內存波動。

有這樣一種情況,有時 SharePreferences.Editor 未用臨時變量存儲,會出現存儲不了數據的情況:
sp.edit().putString(“key”, “value”) // 這樣寫有時會出現存儲不了的情況
SharedPreferences.Editor editor = sp.edit(); // 臨時變量

三、SharedPreference.Editor 的 apply() 和 commit()

1、apply() 沒有返回值,而 commit() 返回 boolean 表明修改是否提交成功。
2、apply() 是將修改數據原子提交到內存,而後異步真正提交到硬件磁盤;而 commit() 是同步的提交到硬件磁盤,因此,在多個併發的提交 commit() 的時候,他們會等待正在處理的 commit() 保存到磁盤後在操作,從而降低了效率。而 apply() 只是原子的提交到內容,後面有調用 apply() 的函數的將會直接覆蓋前面的內存數據,這樣從一定程度上提高了很多效率。commit() 的寫操作是在調用線程中執行的,而 apply() 內部是用一個單線程的線程池實現的,因此寫操作是在子線程中執行的。
3、apply() 方法失敗時,不會有任何失敗的提示。
綜合上述,由於在一個進程中,sharedPreference 是單實例,一般不會出現併發衝突,如果對提交的結果不關心的話,建議使用 apply(),當然需要確保提交成功且有後續操作的話,還是需要用 commit() 的。


參考文章:
1、http://tanqi0508.blog.163.com/blog/static/1883557772012111104326404/
2、https://blog.csdn.net/u012619640/article/details/50940074
3、https://www.cnblogs.com/zhangmiao14/p/7209302.html
4、https://blog.csdn.net/chark_leo/article/details/45564369
5、https://blog.csdn.net/hty1053240123/article/details/79202611

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章