SharedPreference 簡介

SharedPreference

SharedPreference 當存儲 UI 狀態、用戶首選項、應用程序設置時,咱們須要一種輕量級機制以存儲一個已知的值集。SharedPreference 可以保存一組原始數據的名、值對保存爲命名的首選項。java

已保存的應用程序 UI 狀態 當應用程序移動到後臺時,Activity 和 Fragment 會包含專用的事件處理程序以記錄當前的 UI 狀態android

文件 Android 使咱們可以在設備的內部或外部媒體上建立並加載文件,它做爲臨時緩存提供了支持,並將文件存在公用可訪問的文件夾中。緩存


建立並保存 SharedPreference

使用 SharedPreference 類能夠建立名稱/值對,他們能夠在會話之間持久化,並在同一個應用程序沙箱中運行的組件之間共享。安全

SharedPreference 存儲在應用程序的沙箱中,因此能夠在應用程序組件之間共享,可是對其餘應用程序來講不可用。app

在Android系統中, 其配置文件的數據文件 以XML文件的形式保存在 /data/data/PACKAGE_NAME/shared_prefs 目錄下框架

建立 SharedPreference:
SharedPreferences preferences = getSharedPreferences("Jack", Activity.MODE_PRIVATE);異步

Context context = getApplicationContext();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);

修改 SharedPreference:
SharedPreferences.Editor editor = preferences.edit();ide

插入或更新 SharedPreference:函數

editor.putString("TextName", "Jack");
editor.putInt("last", 1);

保存編輯的動做:佈局

// 異步保存
editor.apply();

// 同步保存
editor.commit();


查詢 SharedPreference

使用類型安全的 get<Type> 方法來提取已保存的值,每一個 getter 都接受一個鍵和一個默認值。
也能夠經過 getAll 返回全部的 SharedPreference 鍵值的一個映射。經過調用 contains 方法能夠查詢特定的鍵是否存在。


首選項框架和 Preference Activity

Android 中提供了一個 XML 驅動的框架,用來爲應用程序建立系統樣式的 Preference Screen。經過使用該框架,可以確保應用程序中的 Preference Activity 與本地和其餘第三方應用程序中所使用的一致。

Preference Activity 框架由下面 5 部分組成:

Shared Preference Change Listener

一個 onSharedPreferenceChangeListener 類的實現,用於監聽 SharedPerference 的變化。每當添加、刪除或修改一個特定的 SharedPreference 時來回調該函數。


Preference Screen佈局

一個佈局控制文件,它指定了要顯示的文本和相關控件、所容許的值和爲每一個空間使用的 SharedPreference 鍵。定義XML文件在 res/xml 目錄下。
Preference Screen 文件包含如下幾個元素組成:

  • android:key 在 Shared Preference 中保存的鍵
  • android:title 標題
  • android:summary 描述信息
  • android:defaultValue 默認值
  • android:entries 對應的選項列表
  • android:entrieValues 對應的選項列表的值
  • android:dialogTitle 彈出的列表的 Dialog 的 title

Preference Screen 文件包含如下幾種控件類型:

  • ListPreference 單選列表對話框的控件
  • CheckBoxPreference 一個標準的首選項複選框
  • EditTextPreference 容許用戶輸入一個字符串做爲一個首選項
  • MultiSelectListPreference 在 API Level 11 中引入的,相似於複選框列表
  • RingtonePreference 一個專用的列表首選項,顯示可供用戶選擇的可用鈴聲列表
  • SwitchPreference 開關狀態選擇控件

此外也能夠經過擴展 Preference 類 或上述控件來建立屬於本身的首選項控件。


Preference Fragment:

是從 API Level 11 以後才添加進來的,用來包含 Preference Screen 資源定義。須要繼承此類來建立一個新的 Preference Fragment。
爲 Preference Fragment 填充首選項,須要重寫 onCreate 方法,並調用 addPreferencesFromResource 方法

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.userpreferences);
}


Preference Header 定義

Preference Header 是 XML 資源,存在 res/xml 文件夾下,每一個資源文件名稱就是它的 ID,每一個 Preference Header 必須關聯一個 Preference Fragment,必須指定 Preference Header 的標題。還能夠選擇一個 圖標。
對於不一樣的屏幕尺寸版本,用於顯示頭及其相關 Fragment 的佈局也可能不一樣。


Preference Activity

Preference Activity 類用於包含由 Preference Header 資源定義的 Preference Fragment 層次結構。在 Android 3.0 以前,Preference Activity 用於直接包含 Preference Screen。若是在 Android 3.0 以前運行,則仍是須要直接使用 Preference Activity。

當須要使用 Preference Fragment 和 Preference Header 時,須要重寫 onBuildHeaders 處理程序,在其中調用 loadHeadersFromResources 並指定一個 Preference Header 資源文件:

public void onBuildHeaders(List<Header> target) {
    loadHeadersFromResource(R.xml.preference_headers, target);
}

當裝載 Preference Fragment 和 Preference Header 時,重寫 onCraete 處理程序,在其中調用 addPreferencesFromResource 方法:

public void onCreate(Bundle savedInstanceState) {
    addPreferencesFromResource(R.xml.preference_headers);
}

最後像全部 Activity 程序同樣,在 manifest 文件中添加 activity



經過 Intent 導入系統的首選項,把系統首選項顯示內容添加到 preference screen 中

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
    <intent android:action="android.settings.DISPLAY_SETTINGS" />
</PreferenceScreen>

Preference Fragment 和 Preference Header 是在 Android API Level 11 中才被引入的,低於 API 11 版本的將不會被支持,所以要作一些處理,讓低於 11 版本的 API 繼續使用 Preference Activity。

Class c = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB ? UserPreferencesActivity.class : FragmentPreferences.class;

Intent i = new Intent(this, c);


持久化應用程序實例狀態

若是你想要保存並不須要與其餘組件共享的 Activity 信息(類實例變量),那麼能夠調用 Activity.getPreferences(),而不須要指定一個 SharedPreference 名稱,這會返回一個 SharedPreference,其名稱就是調用 Activity 的名稱。

// 建立或檢索 Activity 首選項對象
SharedPreferences sharedPreferences = this.getPreferences(Activity.MODE_PRIVATE);


使用生命週期處理程序保存和還原 Activity 實例

Activity 提供了 onSaveInstanceState 處理程序來保存與會話之間的 UI 狀態關聯數據,若是 Activity 是由用戶關閉的(或按下 onBack 按鍵)或調用 finish 關閉的。那麼下一次建立 Activity 時,實力狀態 Bundle 是不會傳遞給 onCreate 和 onRestoreInstanceState。

經過重寫一個 Activity 的 onSaveInstanceState 事件處理程序,可使用它的 Bundle 參數來保存 UI 實例的值。每當 Activity 完成了生命週期,可是尚未被顯式的結束(調用 finish)時,該處理程序將會觸發。

protected void onSaveInstanceState(Bundle saveInstanceState) {
    // 檢索視圖
    TextView textView = (TextView) findViewById(R.id.title);

    // 保存狀態
    saveInstanceState.putString(TEXTVIEW_STATE_KEY, textView.getText().toString());

    super.onSaveInstanceState(saveInstanceState);
}

若是應用程序被強制重啓,那麼已保存的 Bundle 參數就會被傳入 onRestoreInstanceSave 和 onCreate 方法中。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView textView = (TextView) findViewById(R.id.title);

    String text = "";
    if (savedInstanceState != null && savedInstanceState.containsKey(TEXTVIEW_STATE_KEY))
        text = savedInstanceState.getString(TEXTVIEW_STATE_KEY);

    textView.setText(text);
}


使用生命週期處理程序保存和還原 Fragment 實例狀態

大多數應用程序的實例都封裝在 Fragment 內,Fragment 也包含一個 onSaveInstanceState 處理程序,其工做方式與 Activity 中的對應處理程序十分類似。

持久化到 Bundle 中的實例狀態做爲參數傳遞給 Fragment 的 onCreate、onCreateView 和 onActivityCreated 處理程序。

在 Activity 被銷燬而後被從新啓動,以及處理硬件配置改變的狀況下,能夠請求保存 Fragment 的狀態。設置 Fragment 的 onCreate 處理程序內的 setRetainInstance 方法爲 true以後,當 Activity 被從新建立時,Fragment 的實例不該該被終止和從新啓動。

所以,當設備配置改變,而且 Activity 被銷燬和從新建立時,Fragment 的 onDestroy 和 onCreate 不會被調用。若是將大部分對象建立代碼移入 onCreate,同時使用 onCreateView 和已保存的實例值中存儲的值來更新 UI,這樣能夠顯著的提交效率。

public static class PlaceholderFragment extends Fragment {

    private static final String USER_SELECTION = "";
    private int userSelection = 0;
    private TextView tv;

    public PlaceholderFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
        if (savedInstanceState != null) {
            userSelection = savedInstanceState.getInt(USER_SELECTION);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);

        tv = (TextView) rootView.findViewById(R.id.text);
        setSelection(userSelection);

        Button button1 = (Button) rootView.findViewById(R.id.button1);
        Button button2 = (Button) rootView.findViewById(R.id.button2);
        Button button3 = (Button) rootView.findViewById(R.id.button3);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setSelection(1);
            }
        });

        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setSelection(2);
            }
        });

        button3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setSelection(3);
            }
        });

        return rootView;
    }

    private void setSelection(int selection) {
        userSelection = selection;
        tv.setText("Selected: " + selection);
    }

    @Override
    public void onSaveInstanceState(Bundle saveInstanceState) {
        saveInstanceState.putInt(USER_SELECTION, userSelection);
        super.onSaveInstanceState(saveInstanceState);
    }
}
相關文章
相關標籤/搜索