1. 程式人生 > >Android 工具類 SharedPreferences 封裝

Android 工具類 SharedPreferences 封裝

state out into bool 替換 ole enc 例子 read

  SharedPreferences 是 Android 數據存儲方式中的一種,特別適合用來存儲少量的、格式簡單的數據,比如應用程序的各種配置信息,如是否打開音效,是否開啟震動等等。

 SharedPreferences 存儲數據的位置和格式

  SharedPreferences 將數據以鍵值對的形式,存儲在 /data/data/<package name>/shared_prefs 目錄下面,以 XML 的格式保存,該 XML 文件的根元素是 <map.../>,該元素裏每個子元素代表一個 key-value 對。

 獲取 SharedPreferences 的三種方式

  要想使用 SharedPreferences,首先需要得到 SharedPreferences 對象。SharedPreferences 本身是一個接口,因此程序無法直接創建 SharedPreferences 的對象,Android 提供了三種獲取 SharedPreferences 對象的方法。

  1、Context 類的 getSharedPreferences(String name, int mode) 方法

      第一個參數用於指定 SharedPreferences 的文件名,第二個參數用於指定操作模式,傳入 MODE_PRIVATE 或者 0 即可,表示只有當前應用程序可以操作SharedPreferences 文件。

  2、Activity 類的 getPreferences(int mode) 方法

     該方法的只接受一個參數,用於指定操作模式,和上面的方法一樣。SharedPreferences 文件名以當前 Activity 的類名命名。該文件屬於當前Activity私有的,只有當前Activity 可以操作。

  3、PreferenceManager 類的 getDefaultSharedPreferences(Context context) 方法

      這是一個靜態方法,接受一個 Context 參數,以當前應用程序的報名作為前綴來命名 SharedPreferences 文件,整個應用程序可以操作。

 SharedPreferences 訪問數據  

    SharedPreferences 中的方法

    得到 SharedPreferences 對象之後,則可以對數據進行讀的操作。SharedPreferences 中提供的公共方法中的 getXXX 方法,即為讀數據,比如

  getInt(String key, int defValue) 就是讀取一個 int 型數據,傳入第一個參數為存儲數據的 key ,第二個參數為默認值,當 key 不存在的時候,會返回該默認值。

    getAll() 方法,會返回 SharedPreferences 中所有的鍵值對。

    contains(String key) 用來判斷 SharedPreferences 所有鍵值對中是否包含鍵為 key 的鍵值對。

    另外 SharedPreferences 中還有一個內部接口,SharedPreferences.OnSharedPreferenceChangeListener ,用來聲明一個回調,當某個 SharedPreferences 改變時會回調該方 法。SharedPreferences 提供了 registerOnSharedPreferenceChangeListener(SharedPreferences.OnSharedPreferenceChangeListener listener) 和          unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) 分別來註冊和取消註冊該回調。

    SharedPreferences.Editor 中的方法

    SharedPreferences 中還有一個方法 edit(),返回 SharedPreferences 的另一個內部接口 SharedPreferences.Editor 對象,該接口提供了諸如 putXXX 方法,很容易猜到是寫 入數據的。同樣拿 putInt(String key, int value) 來說,即往 SharedPreferences 文件中寫入一個鍵值對。值得一提的是,調用 putXXX 方法後,還必須調用 commit() 或者apply() 方法,才能真正寫入數據,這點很容易忘記(本人學習Android時曾踩過坑)。

    clear() 方法,清空 SharedPreferences 中的所有鍵值對。

    remove(String key) 方法,移除鍵為 key 的鍵值對,調用此方法後,需調用 commit 方法才能生效。

    最後還有兩個方法, void apply() 和 boolean commit(),它們都是真正提交某次修改的。這裏主要說說這兩個方法的區別:

      • 從我上面寫出的兩個方法可以看出,apply 方法沒有返回值,apply方法不會提示任何失敗的提示。 commit 方法有返回值,表明修改是否提交成功。
      • 從用法上來說,調用 putXXX 方法之後,調用 apply 或者 commit 方法都可以提交,而調用 remove(String key) 方法之後,需調用 commit 方法提交。
      • 從本質上來說,apply是將修改數據原子提交到內存, 而後異步真正提交到硬件磁盤, 而commit是同步的提交到硬件磁盤,因此,在多個並發的提交commit的時候,他們會等待正在處理的commit保存到磁盤後在操作,從而降低了效率。而apply只是原子的提交到內容,後面有調用apply的函數的將會直接覆蓋前面的內存數據,這樣從一定程度上提高了很多效率。

    由於在一個進程中,sharedPreference是單實例,一般不會出現並發沖突,如果對提交的結果不關心的話,建議使用apply,當然需要確保提交成功且有後續操作的話,還是需要用  commit的。下面寫一個簡單例子,布局文具如下:

技術分享
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.joy.sptest.MainActivity">

    <TextView
        android:id="@+id/tv_show"
        android:layout_marginTop="20dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Hello World!" />

    <Button
        android:id="@+id/btn_write"
        android:layout_marginTop="10dp"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="寫入數據"/>

    <Button
        android:id="@+id/btn_read"
        android:layout_marginTop="10dp"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="讀取數據"/>

    <Button
        android:id="@+id/btn_modify"
        android:layout_marginTop="10dp"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClick"
        android:text="修改數據"/>

</LinearLayout>
技術分享

程序代碼如下:

技術分享
package com.example.joy.sptest;

import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private TextView tvShow;
    private SharedPreferences sp;
    private SharedPreferences.Editor editor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvShow = (TextView) findViewById(R.id.tv_show);
    }

    public void onClick(View v) {
        sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
        switch (v.getId()) {
            case R.id.btn_write:
                editor = sp.edit();
                editor.putString("name", "zhangsan");
                editor.putInt("age", 18);
                if (editor.commit()) {
                    Toast.makeText(MainActivity.this, "提交成功!", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "提交失敗!", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btn_read:
                String name = sp.getString("name", "小明");
                int age = sp.getInt("age", 0);
                tvShow.setText("學生姓名:" + name + "  學生年齡:" + age);
                break;
            case R.id.btn_modify:
                editor = sp.edit();
                editor.putString("name", "張三");
                if (editor.commit()) {
                    Toast.makeText(MainActivity.this, "提交成功!", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "提交失敗!", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}
技術分享

  一個TextView,一開始運行會顯示默認的 “Hello World!”,下面有三個button,點擊寫入數據,調用SharedPreferences,寫入數據,點擊讀取數據,會從 SharedPreferences中讀取數據,並顯示在 textview 上,點擊修改數據,則再次寫入相同的 key ,替換掉之前的 value。程序運行結果如下:

                技術分享

    程序運行textview顯示默認的“Hello World!”,點擊讀取數據,因為找不到 key ,所以返回指定的默認值,點擊寫入數據,寫入姓名"zhangsan",年齡“18”。點擊修改數據,將姓名 改為“張三”。

    通過DDMS文件可以查看,

                技術分享

    在 data/data/com.example.joy.sptest/shared_prefs 目錄下面生成了一個 XML 文件:com.example.joy.sptest_preferences.xml。導出該文件,打開可以看到內容如下:

                技術分享

    最後貼出我自己封裝後常用的讀寫 SharedPreferences 的方法:

技術分享
public static void putSharedPreferences(Context context, String key, Object value) {
        String type = value.getClass().getSimpleName();
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if ("Integer".equals(type)) {
            editor.putInt(key, (Integer) value);
        } else if ("Boolean".equals(type)) {
            editor.putBoolean(key, (Boolean) value);
        } else if ("String".equals(type)) {
            editor.putString(key, (String) value);
        } else if ("Float".equals(type)) {
            editor.putFloat(key, (Float) value);
        } else if ("Long".equals(type)) {
            editor.putLong(key, (Long) value);
        }
        editor.commit();
    }

    public static Object getSharedPreferences(Context context, String key, Object defValue) {
        String type = defValue.getClass().getSimpleName();
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        //defValue為為默認值,如果當前獲取不到數據就返回它
        if ("Integer".equals(type)) {
            return sharedPreferences.getInt(key, (Integer) defValue);
        } else if ("Boolean".equals(type)) {
            return sharedPreferences.getBoolean(key, (Boolean) defValue);
        } else if ("String".equals(type)) {
            return sharedPreferences.getString(key, (String) defValue);
        } else if ("Float".equals(type)) {
            return sharedPreferences.getFloat(key, (Float) defValue);
        } else if ("Long".equals(type)) {
            return sharedPreferences.getLong(key, (Long) defValue);
        }
        return null;
    }
技術分享

Android 工具類 SharedPreferences 封裝