SharedPreferences 是 Android 数据存储方式中的一种,特别适合用来存储少许的、格式简单的数据,好比应用程序的各类配置信息,如是否打开音效,是否开启震动等等。android
SharedPreferences 存储数据的位置和格式并发
SharedPreferences 将数据以键值对的形式,存储在 /data/data/<package name>/shared_prefs 目录下面,以 XML 的格式保存,该 XML 文件的根元素是 <map.../>,该元素里每一个子元素表明一个 key-value 对。app
获取 SharedPreferences 的三种方式异步
要想使用 SharedPreferences,首先须要获得 SharedPreferences 对象。SharedPreferences 自己是一个接口,所以程序没法直接建立 SharedPreferences 的对象,Android 提供了三种获取 SharedPreferences 对象的方法。ide
一、Context 类的 getSharedPreferences(String name, int mode) 方法函数
第一个参数用于指定 SharedPreferences 的文件名,第二个参数用于指定操做模式,传入 MODE_PRIVATE 或者 0 便可,表示只有当前应用程序能够操做SharedPreferences 文件。布局
二、Activity 类的 getPreferences(int mode) 方法学习
该方法的只接受一个参数,用于指定操做模式,和上面的方法同样。SharedPreferences 文件名以当前 Activity 的类名命名。该文件属于当前Activity私有的,只有当前Activity 能够操做。this
三、PreferenceManager 类的 getDefaultSharedPreferences(Context context) 方法spa
这是一个静态方法,接受一个 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(),它们都是真正提交某次修改的。这里主要说说这两个方法的区别:
因为在一个进程中,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; }