码迷,mamicode.com
首页 > 其他好文 > 详细

如何正确的使用SharedPreferences?

时间:2015-06-18 11:38:40      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:

这是我最近碰到过的一个问题,之前并没有一个清晰的认识!唯一的印象是,SharedPreferences 是可以用来存取数据。直到前些日子,在360漏洞扫描应用后,才意识到这个问题,如何正确的使用SharedPreferences呢?以下是360漏洞扫描的信息:

技术分享

关于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:

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所示:

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 来完成多个程序之间的数据共享。


参考文档:

1、http://developer.android.com/reference/android/content/SharedPreferences.html



如何正确的使用SharedPreferences?

标签:

原文地址:http://blog.csdn.net/watermusicyes/article/details/46544943

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!