SharedPreferences 的使用包括两方面:
1)利用 SharedPreferences 读取保存的配置;
2)利用 SharedPreferences 保存用户的配置。
一:有三种获取系统中保存的持久化数据的方式:
1) public SharedPreferences getPreferences (int mode)
通过 Activity 对象获取,获取的是本 Activity 私有的 Preference ,保存在系统中的 xml 形式的文件的名称为这个 Activity 的名字,因此一个 Activity 只能有一个,属于这个 Activity 。
getPreference源码:
public SharedPreferences getPreferences(int mode) { return getSharedPreferences(getLocalClassName(), mode); }
其实getPreferences (int mode)内部还是调用了getSharedPreferences(getLocalClassName(), mode)方法
2)因为 Activity 继承了 ContextWrapper ,因此也是通过 Activity 对象获取,但是属于整个应用程序,可以有多个,以第一参数的 name 为文件名保存在系统中。
public abstract SharedPreferences getSharedPreferences (String name, int mode) eg.sp = getSharedPreferences ("Alarming",0); SharedPreferences preferences; preferences = getSharedPreferences("fileName", MODE_PRIVATE);//fimename是数据库里的文件名,eg.(Alarming.ini)
MODE_PRIVATE:the default mode,only be accessed by the calling application. Constant Value: 0
MODE_WORLD_READABLE:allow all other applications to have read access to the created file.Constant Value: 1
MODE_WORLD_WRITEABLE: allow all other applications to have write access to the created file.Constant Value: 2
//如果modle值为空,则系统默认返回‘你好’。 preferences.getString("modle", "你好"); SharedPreferences.Editor editor = preferences.edit(); //保存组件中的值 editor.putString("modle", "value"); //提交保存的结果 editor.commit();
3) PreferenceManager 的静态函数,保存 PreferenceActivity 中的设置,属于整个应用程序,但是只有一个, Android 会根据包名和 PreferenceActivity 的布局文件来起一个名字保存
SharedPreferences mPerferences = PreferenceManager.getDefaultSharedPreferences(this); int counter = mPerferences.getInt("counter", 0); SharedPreferences.Editor mEditor = mPerferences.edit(); mEditor.putInt("counter", ++counter); mEditor.commit();
查看 Preferences 文件,首先打开命令终端 :adb shell 一下,然后 cd data/data 进入该目录, ls 一下我们会发现一大堆包文件,入下图所示 :
cd com.android.tutor ( 这里是我程序的包名 ) /shared_prefs,ls 一下会发现 .xml 文件如下图 :
打开 .xml 文件,格式如下 ( 为什么这样大家自己去理解 ):
view plaincopy to clipboardprint? <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <int name="counter" value="3" /> </map> <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <int name="counter" value="3" /> </map>
二、使用SharedPreferences存取数据
保存key-value对一般要指定一个文件名,然后用类似putString的方法指定key和value。SharedPreferences也采用了同样的方法。使用SharedPreferences保存key-value对的步骤如下:
(1) 使用Activity类的getSharedPreferences方法获得SharedPreferences对象。其中存储key-value的文件名的名称由getSharedPreferences方法的第一个参数指定。
(2) 使用SharedPreferences接口的edit获得SharedPreferences.Editor对象。
(3) 通过SharedPreferences.Editor接口的putXXX方法保存key-value对。其中XXX表示value的不同数据类型。Boolean类型的value则是用putBoolean方法,字符串类型的则为putString方法。
(4) 通过SharedPreferences.Editor接口的commit方法保存key-value对。Commit方法相当于数据库事务中的提交 (commit)操作。只有在事件结束后进行提交,才会将数据真正保存在数据库中。保存key-value也是一样。
三:数据的存储位置和格式
SharedPreferences将数据文件写在手机内存私有的目录中。在模拟器中测试程序可以通过ADT的DDMS透视图来查看数据文件的位置。
具体的存入和获取操作:
1) 编辑strings.xml :
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, AndroidSharedPreferences!</string> <string name="app_name">Android 应用程序配置</string> <string name="tv_name">姓名</string> <string name="tv_age">年龄</string> <string name="bt_write">设置</string> <string name="bt_read">读取</string> <string name="save_success">保存成功</string> <string name="save_failed">保存失败</string> </resources>
2)编辑main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <!-- 姓名 --> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="70dip" android:layout_height="wrap_content" android:textSize="25dip" android:id="@+id/tv_name" android:text="@string/tv_name" /> <EditText android:layout_width="300dip" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_name" android:id="@+id/et_name" /> </RelativeLayout> <!-- 年龄 --> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content"> <TextView android:layout_width="70dip" android:layout_height="wrap_content" android:textSize="25dip" android:id="@+id/tv_age" android:text="@string/tv_age" /> <EditText android:layout_width="300dip" android:layout_height="wrap_content" android:layout_toRightOf="@id/tv_age" android:id="@+id/et_age" /> </RelativeLayout> <!-- 按钮 --> <RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="right"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bt_write" android:id="@+id/bt_set" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/bt_set" android:text="@string/bt_read" android:id="@+id/et_read" /> </RelativeLayout> </LinearLayout>
3)为按钮添加事件代码
package com.changcheng.sharedpreferences; import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class AndroidSharedPreferences extends Activity { private static final String TAG = "AndroidSharedPreferences"; private EditText etName; private EditText etAge; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取按钮 Button btSet = (Button) this.findViewById(R.id.bt_set); Button btRead = (Button) this.findViewById(R.id.bt_read); // 获取编辑框 etName = (EditText) this.findViewById(R.id.et_name); etAge = (EditText) this.findViewById(R.id.et_age); // 添加事件 btSet.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 获取名称和年龄 String name = etName.getText().toString(); String age = etAge.getText().toString(); // 创建SharedPreferences SharedPreferences sp = getSharedPreferences("preferences", Context.MODE_PRIVATE); // 添加数据 Editor editor = sp.edit(); editor.putString("name", name); editor.putInt("age", Integer.parseInt(age)); // 保存数据 if (editor.commit()) Toast.makeText(AndroidSharedPreferences.this, R.string.save_success, 1).show(); else Toast.makeText(AndroidSharedPreferences.this, R.string.save_failed, 1).show(); } }); btRead.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // 创建SharedPreferences SharedPreferences sp = getSharedPreferences("preferences", Context.MODE_PRIVATE); // 获取数据 String name = sp.getString("name", "defName"); String age = sp.getInt("age", 0) + ""; // 显示数据 etName.setText(name); etAge.setText(age); } }); } }
4)运行程序
启动模拟器,运行程序。输入名称和年龄,点击保存。我们使用的代码是getSharedPreferences("preferences",Context.MODE_PRIVATE); ,当然commit 时。它会为我们为”/data/data/com.changcheng.sharedpreferences/shared_prefs/preferences.xml” 。将 preferences.xml 导出,查看它的内容为:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="name">长城</string> <int name="age" value="25" /> </map
将名称和年龄编辑框的内容清空,然后点击读取按钮,刚才写出的内容被读取进来。 SharedPreferences 的使用就是这么简单。
注:SharedPreferences不仅可以实现应用程序关闭在打开时恢复数据,还可以实现同一个应用程序内部两个Activity之间的数据传递(注意访问权限的设置)。当然不同应用程序间也可以访问他们通过SharedPreferences保存的XML文件,不过这样没有大多的应用价值。
四: 其他程序访问本程序的配置
通过SharedPreferences 创建的配置文件,不需要指定路径和文件后缀名,读取的时候也是。通常情况下,配置只是提供给本应用程序使用的。在这里我们介绍一个小知识点,即其他程序想使用本应用程序的配置,那应该如何使用SharedPreferences 呢?如下:
Context otherAppContext = createPackageContext("com.changcheng.sharedpreferences", Context.CONTEXT_IGNORE_SECURITY); SharedPreferences sharedPreferences = otherAppContext.getSharedPreferences("preferences", Context.MODE_WORLD_READABLE);
注意,为了使其他程序可以访问本应用程序的配置。那么在我们使用 getSharedPreferences 创建配置的时候必须为它的文件访问模式设置为允许其他程序读取或写入等。