zoukankan      html  css  js  c++  java
  • 【通过做专题研习Android】知识点:SharedPreferences

    Ⅰ. 一个简短的引论

    很多时候我们需要开发软件,为用户提供软件参数设置功能,比如,我们经常使用 QQ。用户可以设置自己是否同意加入一个陌生人为好友。对于软件的配置参数的存储,假设window採用ini文件进行保存,假设是j2se应用,我们会採用properties属性文件或者xml进行保存。假设是Android应用,我们最适合採用什么方式保存软件配置參数呢?Android 平台给我们提供了一个SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置參数。

    SharedPreferences 类似过去Windows系统上的ini配置文件,可是它分为多种权限。能够全局共享訪问,终于是以xml方式来保存,总体效率来看不是特别的高,对于常规的轻量级而言比SQLite要好不少,假设真的存储量不大能够考虑自定义文件格式。xml 处理时Dalvik会通过自带底层的本地XML Parser解析,比方XMLpull方式,这样对于内存资源占用比較好。

    使用 SharedPreferences保存数据。其背后是用xml文件存放数据。文件存放在/data/data/<package name>/shared_prefs文件夹下(须要用户的root权限)

    SharedPreferences的使用很easy,可以轻松的存放数据和读取数据。SharedPreferences仅仅能保存简单类型的数据,比如。String、int等。通常会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件里,再用SharedPreferences保存。这种方式应该是用起来最简单的Android读写外部数据的方法了。他的使用方法基本上和 J2SE(java.util.prefs.Preferences)中的使用方法一样,以一种简单、透明的方式来保存一些用户个性化设置的字体、颜色、位置等參数信息。

    一般的应用程序都会提供“设置”或者“首选项”的这种界面,那么这些设置最后就行 通过Preferences来保存,而程序猿不须要知道它究竟以什么形式保存的,保存在了什么地方。当然。假设你愿意保存其它的东西,也没有什么限制。仅仅 是在性能上不知道会有什么问题。


    Ⅱ. 使用

    使用SharedPreferences保存key-value对的过程例如以下:

    (1)使用Activity类的getSharedPreferences方法获得SharedPreferences对象,当中存储key-value的文件的名称由getSharedPreferences方法的第一个參数指定。

    (2)使用SharedPreferences接口的edit获得SharedPreferences.Editor对象。

    (3)通过SharedPreferences.Editor接口的putXxx方法保存key-value对。

    当中Xxx表示不同的数据类型。

    比如:字符串类型的value须要用putString方法。

    (4)通过SharedPreferences.Editor接口的commit方法保存key-value对。

    commit方法相当于数据库事务中的提交(commit)操作。


    详细代码的书写流程为:

    A、存放数据信息

    //1、打开Preferences。名称为setting。假设存在则打开它,否则创建新的Preferences
    
    SharedPreferences settings = getSharedPreferences(“setting”, 0);
    
    //2、让setting处于编辑状态
    
    SharedPreferences.Editor editor = settings.edit();
    
    //3、存放数据
    
    editor.putString(“name”,”ATAAW”);
    
    editor.putString(“URL”,”ATAAW.COM”);
    
    //4、完毕提交
    
    editor.commit();

    由于SharedPreferences背后是使用xml文件保存数据。getSharedPreferences(name,mode)方法的第一个參数用于指定该文件的名称,名称不用带后缀,后缀会由Android自己主动加上。

    方法的第二个參数指定文件的操作模式,共同拥有四种操作模式。

    • Activity.MODE_PRIVATE,//默认操作模式,代表该文件是私有数据,仅仅能被应用本身訪问。在该模式下,写入的内容会覆盖原文件的内容,假设想把新写入的内容追加到原文件里。能够使用Activity.MODE_APPEND 
    • Activity.MODE_WORLD_READABLE,//表示当前文件能够被其它应用读取。 
    • Activity.MODE_WORLD_WRITEABLE,//表示当前文件能够被其它应用写入; 
                                           //假设希望文件被其它应用读和写,能够传入:Activity.MODE_WORLD_READABLE+Activity.MODE_WORLD_WRITEABLE
    • Activity.MODE_APPEND//该模式会检查文件是否存在。存在就往文件追加内容。否则就创建新文件 

    假设希望SharedPreferences背后使用的xml文件能被其它应用读和写,能够指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。

    另外Activity还提供了还有一个getPreferences(mode)方法操作SharedPreferences。这种方法默认使用当前类不带包名的类名作为文件的名称。


    B、读取数据信息

    //1、获取Preferences
    
    SharedPreferences settings = getSharedPreferences(“setting”, 0);
    
    //2、取出数据
    
    String name = settings.getString(“name”,”默认值”);//getString()第二个參数为缺省值,假设preference中不存在该key,将返回缺省值
    
    String url = setting.getString(“URL”,”default”);

    //以上就是Android中SharedPreferences的用法,当中创建的Preferences文件存放位置能够在Eclipse中查看:

    DDMS->File Explorer /<package name>/shared_prefs/setting.xml


    执行机制

    Context内部实现

    getSharedPreferences()方法本身是Context这个接口中定义的一个抽象方法,由ContextImpl类负责实现。

    1 、调用getSharedPreferences()获取相应的的文件,该函数实现功能例如以下:

    //Context类静态数据集合,以键值对保存了全部读取该xml文件后所形成的数据集合
    private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
       new HashMap<File, SharedPreferencesImpl>();
     
    @Override
    public SharedPreferences getSharedPreferences(String name, int mode){
    //其所相应的SharedPreferencesImpl对象 ,该对象已一个HashMap集合保存了我们对该文件序列化结果
    SharedPreferencesImpl sp; 
         File f = getSharedPrefsFile(name);  //该包下是否存在相应的文件。不存在就新建一个
         synchronized (sSharedPrefs) {       //是否已经读取过该文件。是就直接返回该SharedPreferences对象
             sp = sSharedPrefs.get(f);
             if (sp != null && !sp.hasFileChanged()) {
                 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
                 return sp;
             }
         }
         //下面为序列化该xml文件,同一时候将数据写到map集合中    
         Map map = null;
         if (f.exists() && f.canRead()) {
             try {
                 str = new FileInputStream(f);
                 map = XmlUtils.readMapXml(str);
                 str.close();
             }
             ...
         }
        
         synchronized (sSharedPrefs) {
             if (sp != null) {
                 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
                 sp.replace(map);   //更新数据集合
             } else {
                 sp = sSharedPrefs.get(f);
                 if (sp == null) { 
                  //新建一个SharedPreferencesImpl对象,而且设置其相关属性
                     sp = new SharedPreferencesImpl(f, mode, map); 
                     sSharedPrefs.put(f, sp);
                 }
             }
             return sp;
         }
    }

    2、 SharedPreferences 只是是个接口。它定义了一些操作xml文件的方法,其真正实现类为SharedPreferencesImpl ,该类是ContextIml的内部类,该类例如以下:

    //这样的形式我们在分析Context ContextIml时接触过
    //SharedPreferences仅仅是一种接口,其真正实现类是SharedPreferencesImpl类
    private static final class SharedPreferencesImpl implements SharedPreferences{
    private Map mMap;  //保存了该文件序列化结果后的操作。 键值对形式
    //通过key值获取相应的value值
    public String getString(String key, String defValue) {
             synchronized (this) {
                 String v = (String)mMap.get(key);
                 return v != null ? v : defValue;
             }
         }
    ...
    //获得该SharedPreferencesImpl对象相应的Edito类。对数据进行操作
    public final class EditorImpl implements Editor {
    private final Map<String, Object> mModified = Maps.newHashMap(); //保存了对键值变化的集合
    }
    } 


     

    參考:

    http://blog.csdn.net/wxyyxc1992/article/details/17222841

    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    CODING x 百果园 _ 水果零售龙头迈出 DevOps 体系建设第一步
    Nocalhost 亮相 CD Foundation 国内首届 Meetup,Keith Chan 将出席致辞
    做云原生时代标准化工具,实现高效云上研发工作流
    打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
    WePack —— 助力企业渐进式 DevOps 转型
    CODING Compass —— 打造行云流水般的软件工厂
    Nocalhost —— 让云原生开发回归原始而又简单
    CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全
    Nocalhost:云原生开发新体验
    使用 Nocalhost 开发 Kubernetes 中的 APISIX Ingress Controller
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4777756.html
Copyright © 2011-2022 走看看