Android(安卓)- SharedPreferences
SharedPreference是Android提供的一种轻量级的数据存储方式,主要以键值对的形式存储一些简单的数据。
比如第一次打开某个应用时需要弹出一个提示框,并且这个提示框上还要一个“以后不再提醒”的选项,这种情况我们就可以考虑使用SharedPreference来记住用户的选择情况,以后用户再次打开应用时就根据之前的选择来判断要不要给出提示。
那么,问题就来了,比如当用户第一次选择了下次不再提醒,那么,相应的数据是以什么方式,存在什么地方?当用户以后打开应用,又怎么读之前存储的数据?… …
先上代码:
public class MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) {... ...promptUser();}private void promptUser() {//获得SharedPreferences对象mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);//读取数据 boolean isPromp = mSharedPreferences.getBoolean(prompkey, false); if(!isPromp){ showPrompDialog(); }}private void showPrompDialog() {AlertDialog.Builder builder = new AlertDialog.Builder(this); LayoutInflater factory = LayoutInflater.from(this); final View promptUserView = factory.inflate(R.layout.promptuser_layout, null);builder.setTitle(R.string.promptuser_title);builder.setMessage(R.string.promptuser_content);builder.setView(promptUserView); builder.setPositiveButton(R.string.btn_ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { CheckBox mCheckBox = (CheckBox)promptUserView.findViewById(R.id.checkBox);Boolean isChecked = mCheckBox.isChecked();//获得Editor对象Editor mEditor =mSharedPreferences.edit().putBoolean(prompkey, isChecked);//提交修改mEditor.commit();} }); builder.setNegativeButton(R.string.btn_no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) {} }); builder.create().show(); }}
在使用SharedPreferences时,我们首先需要获取SharedPreferences对象,SharedPreferences的获取有两种方法:一是通过Activity的getSharedPreferences方法(本质上来讲,该方法是在Context.java中定义的):
/** * Retrieve and hold the contents of the preferences file 'name', returning * a SharedPreferences through which you can retrieve and modify its * values. Only one instance of the SharedPreferences object is returned * to any callers for the same name, meaning they will see each other's * edits as soon as they are made. * ... ... */ public abstract SharedPreferences getSharedPreferences(String name, int mode);第一个参数为文件名,如果和name对应的preference file 不存在,那么(以下是API中的说明):
it will be created when you retrieve aneditor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
第二个参数为权限,共有4中选择:MODE_PRIVATE、MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE、MODE_MULTI_PROCESS (Use 0 or {@link #MODE_PRIVATE} for thedefault operation)
另一种是通过PreferenceManager类的静态方法getDefaultSharedPreferences ()获取SharedPreferences对象。
那这两种方法有什么区别呢?
使用SharedPreferences存取数据实质上就是对/data/data/<package name>/shared_prefs路径下的xml文件进行读写操作,这就涉及到这个xml文件的文件名和读写权限,使用这两种方法的区别主要就是文件名和权限设置上的区别。
使用第一种方法,我们可以通过第一个参数指定对应的xml文件的文件名,通过第二个参数指定该xml文件的读写权限。
使用第二种方法时,通过PreferenceManager.java的源码我们可以发现:
/** * Gets a SharedPreferences instance that points to the default file that is * used by the preference framework in the given context. * * @param context The context of the preferences whose values are wanted. * @return A SharedPreferences instance that can be used to retrieve and * listen to values of the preferences. */ public static SharedPreferences getDefaultSharedPreferences(Context context) { return context.getSharedPreferences(getDefaultSharedPreferencesName(context), getDefaultSharedPreferencesMode()); } private static String getDefaultSharedPreferencesName(Context context) { return context.getPackageName() + "_preferences"; } private static int getDefaultSharedPreferencesMode() { return Context.MODE_PRIVATE; }这种方式其实是调用了Context的getSharedPreferences方法,并且,将preference对应的文件名设置为"包名_preferences",将权限设置为MODE_PRIVATE。
知道两种方式的区别后,我们在使用的时候,就很好选择了。
如果在一个应用中只需要用到一个文件来存储,那我们选择PreferenceManager类的静态方法getDefaultSharedPreferences (),如果需要用多个文件来存储数据,那就选择Activity的getSharedPreferences方法获取SharedPreferences对象以方便根据文件名进行区分,不过可以从这两个方法的实现逻辑看出来,PreferenceManager类的静态方法getDefaultSharedPreferences ()内部调用了Context的getSharedPreferences方法,并且,文件名和权限都是通过get...方法获取到的,所以使用getDefaultSharedPreferences方法会更影响效率一些。
在获取到preference对象之后,通过查阅API我们可以看到,获取数据主要靠SharedPreferences
的getString,getInt,getLong,getFloat,getBoolean等方法,我们就看看getString()方法的定义吧
/** * Retrieve a String value from the preferences. * * @param key The name of the preference to retrieve. * @param defValue Value to return if this preference does not exist. * * @return Returns the preference value if it exists, or defValue. Throws * ClassCastException if there is a preference with this name that is not * a String. * *///返回指定的key对应的value,如果不存在返回defValue String getString(String key, String defValue);
如果需要写数据,则需要在获取到SharedPreferences对象之后,通过Sharedpreference.edit()方法获取编辑器Editor对象,利用Editor的putString,putInt,putLong,putFloat,putBoolean等方法来完成。从API里我们也可以看出SharedPreferences所支持存储的数据类型是哪些。Editor及putString()方法(其他put方法同)的代码如下:
/** * Interface used for modifying values in a {@link SharedPreferences} * object. All changes you make in an editor are batched, and not copied * back to the original {@link SharedPreferences} until you call {@link #commit} * or {@link #apply} */ public interface Editor { /** * Set a String value in the preferences editor, to be written back once * {@link #commit} or {@link #apply} are called. * * @param key The name of the preference to modify. * @param value The new value for the preference. Supplying {@code null} * as the value is equivalent to calling {@link #remove(String)} with * this key. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. */ Editor putString(String key, String value);
最后再调用commit()提交设置,写入xml文件。
在写完数据提交时,commit()方法和apply()方法也是有区别的(待补充) ... ...
现在,我们来看一下在这个Demo中生成的文件,我们可以进入到data/data/<package name>/shared_prefs路径下将对应的xml文件导入到本地打开查看:
也可以在黑框中通过adb命令来查看该xml文件:
另外还涉及到的类是:
SharedPreferences. OnSharedPreferenceChangeListener
未完待续 ... ...
更多相关文章
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- Android(安卓)的性能 V-保持APP的响应
- Android(安卓)加载大图片造成OOM异常解决方法
- lame音频压缩解码(二)之编译事例Demo
- Android(安卓)Ndk: 如何从native层直接获取 assets文件夹下的文
- Android(安卓)NDK开发入门实例