如何正确的使用SharedPreferences

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何正确的使用SharedPreferences相关的知识,希望对你有一定的参考价值。

关于SharedPreferences顺便再复习一下:

SharedPreferences 是android 中的内置API,它允许我们存取键值对形式的基础类型数据,像:boolean,float ,int , long , string 。这些数据将会持久化的存在,即使你的应用程序结束之后(注意:如果应用从手机上写在掉后,该程序对应的SharedPreferences将会消失,保存在路径:/data/data/<package_name>/shared_prefs 目录下)

注意:User Preferences 用户配置

严格来说,SharedPreferences最好不要用来保存“用户配置”,比如,用户选择了什么铃声,是否自动更新等等。如果要为应用创建用户配置,可以使用PreferenceActivity,它可以用来创建“用户配置”。(PreferenceActivity用来创建程序中的设置界面)

如何在应用程序中获取SharedPreferences呢?有两个方法:

getSharedPreferences(name , mode) - 如果你的应用需要多个preferences文件可以使用该方法。该方法的第一个参数,用来区别不同的preferences文件。
比如:

SharedPreferences sp1 = getSharedPreferences("sp_1" , Context.MODE_PRIVATE);
SharedPreferences sp2 = getSharedPreferences("sp_2" , Context.MODE_PRIVATE);
是同一个应用程序的两个不同的配置文件。

该方法的第二个参数支持如下几种值:
Context.MODE_PRIVATE:指定该SharedPreferences数据只能被本应用程序或者是拥有相同user ID的应用读、写。

Context.MODE_WORLD_READABLE :指定该SharedPreferences数据能被其它应用程序读,但不能写。
这个变量在API 17以后已经不建议使用了。创建全局可读文件是非常危险的事,这样会引起程序的安全漏洞。程序之间的交互应该更多的使用正规的途径,比如:ContentProvider, BroadcastReceiver, and Service.当程序通过备份和恢复后,并不能保证这种获取方式依然对该文件有效。文件创建模式:允许所有的其它程序来读取创建的文件。
Context.MODE_WORLD_WRITEABLE:指定该SharedPreferences数据能被其它应用程序读,写。

这个变量在API 17以后已经不建议使用了。创建全局可写文件是非常危险的事,这样会引起程序的安全漏洞.程序之间的交互应该更多的使用正规的途径,比如:ContentProvider, BroadcastReceiver, and Service.当程序通过备份和恢复后,并不能保证这种获取方式依然对文件有效。文件创建模式:允许所有的其它程序来修改创建的文件。

Context.MODE_MULTI_PROCESS
在API11中添加,SharedPreferences加载标记:被设置后,在硬盘上的文件在被修改是将会被检查如果当前的SharedPreferences实例已经被加载进进程后。这种情况通常发生在,当程序有多个进程在修改同一个SharedPreferences文件的时候。通常来说这种方式在进程之间交互表现是非常好的。

在API 2.3之前,发布release版本时,这个标记是默认存在的,当发布release版本时。对于使用2.3以上的sdk进行编译的时候,如果想使用那么
必须明确的设置。

getPreferences() - 如果你的Activity仅仅需要一个preferences文件可以使用这个方法。因为你的Activity只要一个preferences文件,所以不需要提供名字。

如何往SharedPreferences中写数据呢?

1、需要获取SharedPreferences的编辑对象即:SharedPreferences.Editor : 使用 edit()。
比如:SharedPreferences.Editor editor = sp1.edit();
2、使用putXXX()方法,向preferences写入数据:
比如:editor.putXXX(“key” , value);
3、向preferences文件中提交数据:
比如:editor.commit();

如何读取数据呢?
使用方法getXXX()等方法读取。
比如:
boolean silent = settings.getBoolean("silentMode", false);

下面是Google doc提供的一个demo:
[java] view plaincopyprint?
public class Calc extends Activity
public static final String PREFS_NAME = "MyPrefsFile";

@Override
protected void onCreate(Bundle state)
super.onCreate(state);
. . .

// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);


@Override
protected void onStop()
super.onStop();

// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);

// Commit the edits!
editor.commit();



接下来看Google doc 中关于sharedpreferences的文档。

SharedPreferences 本身是一个接口,用来获取和修改程序的配置数据,位于:android.content.SharedPreferences。程序无法直接创建SharedPreferences实例,只能通过conext的getSharedPreferences(String, int)的获取接口实例。

注意:当前类不支持跨进程调用,将会在之后的版本中支持。

它提供了如下方法来访问perferences数据:

boolean contains(String key) :判断当前preferences是否包含key所对应的数据。

abstract SharedPreferences.Editor edit():为preferences创建一个新的Editor,因此你可以修改preferences的数据并且提交给SharedPreferences对象。

abstract Map<String, ?> getAll() :获取preferences中所包含的所有数据。

abstract XXX getXXX(String key, boolean defValue):获取perferences里指定的key对应的value。如果该key不存在,则返回默认defValue .其中XXX是基础数据类型:boolean、float、int、long、String等。

SharedPreferences接口本身并没有提供写入数据的能力,而是通过SharedPreferences的内部接口,SharedPreferences调用edit()方法即可获取它所对应的Editor对象。

Editor提供了如下方法来写向perferences入数据:

abstract SharedPreferences.Editor clear()
在Editor中标记出:清除所有preferences保存的数据。(注意此方法并没有实质性的清除,只是在Editor上进行了标记,需要commit后才可以进行真正的清除)

abstract boolean commit():
将Editor对preferences的修改提交给SharedPreferences对象,完成对preferences中数据的修改。

abstract SharedPreferences.Editor putXXX(String key, boolean value)
向preferences中存入key及其所对应的数据 <key-value>。其中xxx可以是boolean、float、int、long、String等各种基本类型的数值。

abstract SharedPreferences.Editor remove(String key):
在Editor中标记出preference中以key以键的键值对应该被移除,而实际的移除动作将会在commit()执行之后才会作用于真正的preferences。

如何读取其它应用的SharedPreferences:

如上所述,如果想读、写其它应用的SharedPreferences,前提是创建该SharedPreferences的应用程序指定相应的访问权限,例如指定了MODE_WORLD_READABLE , 这表明该SharedPreferences可被其它应用程序读取。指定了MODE_WORLD_WRITEABLE,这表明该SharedPreferences可被其它程序写入。

为了读取其它程序对应的Context,可按照如下步骤进行:
1、需要创建其它程序对应的Context,例如如下代码:
Context userCount = createPackageContext(“com.sharedpreferencesdemo.zhanggeng” , Context.CONTEXT_IGNORE_SECURITY);

上面的程序中:com.sharedpreferencesdemo.zhanggeng 就是其他程序的包名——实际上Android系统就是用应用程序的报名来作为程序的标识的。
2、调用其它程序的conext的getSharedPreferences(String name , int mode) 即可获取相应的SharedPreferences对象。
3、调用SharedPreferences的edit()方法获取相应的Editor即可。

如下demo所示:
[java] view plaincopyprint?
private void readOtherAppSp()
Context useCount = null;

try
//获取其它程序对应的Context
useCount = createPackageContext("com.sharedpreferencesdemo.zhanggeng" , Context.CONTEXT_IGNORE_SECURITY);
catch (PackageManager.NameNotFoundException e)
e.printStackTrace();

//使用其它程序的Context获取对应的SharedPreferences
SharedPreferences prefs = useCount.getSharedPreferences("count" , Context.MODE_WORLD_READABLE);
//读取数据
int count = prefs.getInt("count" , 0);
//后续处理.....


那么回到最初的问题,改如何正确的使用SharedPreferences?
1、设置相应的权限:如果只供本程序或者有相同user id的程序使用 使用Context.MODE_PRIVATE权限;如果允许其它程序可读设置权限;如果允许其它程序可写设置相应权限;
2、SharedPreferences保存的数据最好是基础数据类型(当然也可以用来保存用户配置,官方推荐PreferenceActivtiy )。
3、如果想让程序有多个preferences文件使用getSharedPreferences(xxx , xxx);如果想让程序只有一个preferences使用getPreferences()。
4、SharedPreferences最好不要用来保存多个程序交互使用的共享数据,建议使用ContentProvider, BroadcastReceiver, and Service 来完成多个程序之间的数据共享。
参考技术A 于SharedPreferences顺便再复习一下: SharedPreferences 是Android 中的内置API,它允许我们存取键值对形式的基础类型数据,像:boolean,float ,int , long , string 。这些数据将会持久化的存在,即使你的应用程序结束之后(注意:如果应用... 参考技术B 首先不懂你的服务器搭在哪了?SharedPreferences是Android系统提供的数据保存工具吧。我想你的意思是问服务器端如何使用客户端的SharedPreferences数据,(SharedPreferences具体你可以百度)。 服务器端如何使用客户端的SharedPreferences数据,...

以上是关于如何正确的使用SharedPreferences的主要内容,如果未能解决你的问题,请参考以下文章

如何正确使用 Composer 安装 Laravel 扩展包

如何正确使用 Composer 安装 Laravel 扩展包

如何正确强制正确使用类方法?

如何正确使用 Composer 安装 Laravel 扩展包

如何正确的使用QWebEngineView

如何正确使用 CBVs