標籤:listener app default roi appcompat err 修改 case sha
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 封裝