Android 数据存储(一)SharedPreferences

转载请注明出处:http://www.jianshu.com/p/21b266d6b6d7

这篇主要简单介绍一下Android中存储数据的几种方式,然后具体分析下SharedPreferences的使用方法。


1 简介

Android提供了几个选项来保存持久的应用程序数据。 您选择的解决方案取决于您的具体需求,例如数据是否应该是您的应用程序私有的或其他应用程序(和用户)可访问的数据以及数据所需的空间。
数据存储选项如下:

  • Shared Preferences 保存私人基本数据(键值对)。
  • Internal Storage 将专有数据存储在设备内存中。
  • External Storage 将公共数据存储在共享的外部存储上。
  • SQLite Databases 将结构化数据存储在专用数据库中。
  • Network Connection 使用自己的网络服务器将数据存储在网络上。

Android提供了一种让您将私人数据暴露给其他应用程序的方式 - ContetProvider。ContetProvider是一个可选组件,可以暴露对应用程序数据的读/写访问权限,无论您想要施加什么限制。
这篇主要说一下SharedPreferences使用方法。
SharedPreferences是Android提供的一种存储数据的机制,用于存储少量数据,数据类型包括(boolean 、int、long、float、string),主要用于存储应用的配置信息,例如:用户名、密码、是否开启震动、音乐等。
它实际上是以键值对的形式储存在xml文件中。存储位置:data/data/程序包名/shared_prefs/ 目录下。


2 保存数据

先看下代码:

mPreferences = getSharedPreferences("test", Context.MODE_PRIVATE);
mEditor = mPreferences.edit();
mEditor.putInt("int", 1);
mEditor.putBoolean("boolean", true);
mEditor.putFloat("float", 3.14f);
mEditor.putLong("long", 123l);
mEditor.putString("string", "abcd");
mEditor.commit();
mPreferences.registerOnSharedPreferenceChangeListener(mListener);

第1行 通过context获取SharedPreferences对象SharedPreferences
第一个参数表示要操作的xml文件名。
第二个参数 操作模式,操作模式如下:Context类中的变量,类型为public static final int。

  • MODE_PRIVATE = 0x0000; 0 默认模式,指定该SharedPreferences数据只能被本应用程序读、写。
  • MODE_WORLD_READABLE = 0x0001; 1 指定数据可以被其他应用程序读,但不能写。
    创建可读的文件是很危险的,而且可能以引起应用程序的安全漏洞。强烈劝阻;相反,应用程序应该使用的互动更加正式的机制 如{ContentProvider},{BroadcastReceiver}和{android.app.Service}。此变量在API级别17中已被弃用。
  • MODE_WORLD_WRITEABLE = 0x0002; 2 指定数据可以被其他应用程序写,但不能读。
    创建可写文件也是危险的,不推荐使用。此变量在API级别17中已被弃用。
  • MODE_MULTI_PROCESS = 0x0004; 4 文件将会在SharedPreference实例被装载到进程的时候检查是否被修改,主要用在一个应用有多个进程的情况。

第2行 获取Editor对象,通过editor对象来更改SharedPreferences中的内容。
第3~7行 设置键值对。
第8行 提交修改。(很重要,如果不执行则并没有更改数据)。

查看下Editor的一些方法:


Editor方法

以put开头的是设置键值对的方法。rmove方法用来移除某键值对。
apply() 和commit()都可以用来保存修改。

  • commit()有返回值,成功返回true,失败返回false。将内容修改从编辑器提交到SharedPreferences对象,这是原子到执行修改,替换当前在SharedPreferences中的任何内容。注意:当两个编辑器同时修改内容时,最后一个调用提交覆盖之前的更改。如果不关心返回值,并且从应用程序的主线程中使用该值,请考虑使用apply()。return 如果返回true,则表示将新值写入持久存储(硬件磁盘)成功,否则表示写入失败。
  • apply()没有返回值,apply()是将修改的数据提交到内存, 而后异步真正的提交到硬件磁盘,不会通知任何失败。
    如果SharedPreferences的另一个编辑器editor在apply异步提交伤胃完成时定期进行commit,则commit将阻塞,直到所有异步提交完成。
    由于SharedPreferences在一个进程中是单列的,如果忽略了返回值,可以安全的替换任何commit 到apply。

我这个代码包名是cn.vn.sharedpreferencesdemo,所以xml文件路径为:/data/data/cn.vn.sharedpreferencesdemo/shared_prefs/test.xml。
内容如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <boolean name="boolean" value="true" />
    <long name="long" value="123" />
    <float name="float" value="3.14" />
    <int name="int" value="1" />
    <string name="string">abcd</string>
</map>

3 获取数据

代码如下:

int a = mPreferences.getInt("int", 0);
boolean bool = mPreferences.getBoolean("boolean", false);
float f = mPreferences.getFloat("float", 0.0f);
long l = mPreferences.getLong("long", 0);
String s = mPreferences.getString("string", "");
String wifi = mPreferences.getString("wifi", "5566");

变量值如下:

06-27 11:55:42.328 I/MainActivity( 2408): a=1
06-27 11:55:42.328 I/MainActivity( 2408): bool=true
06-27 11:55:42.328 I/MainActivity( 2408): f=3.14
06-27 11:55:42.328 I/MainActivity( 2408): l=123
06-27 11:55:42.328 I/MainActivity( 2408): s=abcd
06-27 11:55:42.328 I/MainActivity( 2408): wifi=5566

以getInt为例,第一个参数为键值,第二个参数为默认值(如果SharedPreferences中没有该键值则返回该值)。其他道理类似。


4 监听数据改变

SharedPreferences类中提供了监听数据变化的接口,代码如下

private OnSharedPreferenceChangeListener mListener= 
        new OnSharedPreferenceChangeListener() {
    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        Log.i(TAG, "Changed key="+key);
    }
};
//注册监听
mPreferences.registerOnSharedPreferenceChangeListener(mListener);

当SharedPreferences中的数据修改后,会回调mListener中的onSharedPreferenceChanged方法,通过参数key可以知道哪个键值进行了变动。
我们来尝试修改一下:

mEditor.putInt("int", 1);
mEditor.putString("string", "ab");
mEditor.remove("long");
mEditor.commit();

打印如下:

06-27 11:55:47.015 I/MainActivity( 2408): Changed key=string
06-27 11:55:47.015 I/MainActivity( 2408): Changed key=long

由于原先的int键对应的值为1,该值没有改变,所以不会回调onSharedPreferenceChanged。而string键的值由abcd变成了ab,删除了long键,所以这两个键更改都有回调。

取消监听SharedPreference

mPreferences.unregisterOnSharedPreferenceChangeListener(mListener);

以上就是SharedPreferences的简单用法。其中还有一些坑需要去走。

欢迎大家关注、评论、点赞
你们的支持是我坚持的动力。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容