保存简单的应用程序数据---SharedPreferences浅析

          1.SharedPreferences简介

  

             SharedPreferences 是Android提供的一种简单、通用的数据持久化技术,它使用名称/值对(NVP)机制来存储简单的基本值,支持基本类型,包括布尔型、字符串、多维字符串(StringSet)、浮点型、长整型、整型,一般用于存储一些配置信息,可以在会话之间持久化,并在同一个应用程序沙箱中运行的应用程序组件之间共享。


          2. 源码浅析:   

                

public interface SharedPreferences {
    
    public interface OnSharedPreferenceChangeListener {
      
        void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);
    }
    
   
    public interface Editor {
      
        Editor putString(String key, String value);
       
        Editor putStringSet(String key, Set<String> values);
       
        Editor putInt(String key, int value);
   
        Editor putLong(String key, long value);
        
        Editor putFloat(String key, float value);  
       
        Editor putBoolean(String key, boolean value);

        Editor remove(String key);
 
        Editor clear();
   
        boolean commit();
   
        void apply();
    }

   
    Map<String, ?> getAll();

    String getString(String key, String defValue);
    
    Set<String> getStringSet(String key, Set<String> defValues);
    
    int getInt(String key, int defValue);
    
    long getLong(String key, long defValue);
    
    float getFloat(String key, float defValue);
    
    boolean getBoolean(String key, boolean defValue);

    boolean contains(String key);
   
    Editor edit();
    
    void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);
    
    void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);
}

    

          首先,我们注意到SharedPreference 是一个接口,通过Editor这个内部接口来实现存储基本数据(字符串、字符串集合、整型、浮点型、长整形、布尔型)和清除、删除、提交数据,而自己则实现获得数据、查询数据、得到Editor并且监听数据更改的动作。

         实现类则在SharedPreferencesImpl这个类中:

     

final class SharedPreferencesImpl implements SharedPreferences {

    private final File mFile;       //硬盘文件
    private final File mBackupFile; //备份文件
    private final int mMode;        //文件操作模式

    private Map<String, Object> mMap;     // 保存数据
    private boolean mLoaded = false;      // 加载完的标志

    SharedPreferencesImpl(File file, int mode) {
        mFile = file;
        mBackupFile = makeBackupFile(file);
        mMode = mode;
        mLoaded = false;
        mMap = null;
        startLoadFromDisk();//开始从硬盘上异步加载
    }<span style="font-family: Arial, Helvetica, sans-serif;">   </span>
   /* 四种Mode :
    * MODE_PRIVATE      私有,只能被应用程序本身访问
    * MODE_APPEND       如果存在就添加在其后,不存在就创建新文件
    * MODE_WORLD_READABLE       其他应用程序可以读
    * MODE_WORLD_WRITEABLE  <span style="font-family: Arial, Helvetica, sans-serif;">   其他应用程序可以写  */</span>
 
      public Editor edit() {  //需要获得这个实例才能操作sharedPreferences数据。

        synchronized (this) {
            awaitLoadedLocked();
        }
        return new EditorImpl();
    }
 public final class EditorImpl implements Editor {  //继续 EditorImpl

        private final Map<String, Object> mModified = Maps.newHashMap();//缓存数据类,其后会以文件的形式存入硬盘
        private boolean mClear = false;

        public Editor putString(String key, String value) {
            synchronized (this) {
                mModified.put(key, value);//对SharedPreferences操作即是对mModified进行操作
                return this;
            }
        }
        public Editor putStringSet(String key, Set<String> values) {
            synchronized (this) {
                mModified.put(key,
                        (values == null) ? null : new HashSet<String>(values));
                return this;
            }
        }
        // ....部分省略
        public Editor remove(String key) {
            synchronized (this) {
                mModified.put(key, this);//注意,并不是直接remove
                return this;
            }
        }

        public Editor clear() {
            synchronized (this) {
                mClear = true;
                return this;
            }
        }

       }


    3.一些小技巧

           1.获得SharedPreferences的三种方式

                Context.getSharedPreferences(String name,int mode);//指定文件名

                Activity.getPreferences(int mode);

                PreferenceManager.getDefaultSharedPreference(Context context);


          2.使用链式编程添加多个不同类型的键值对

              由于edit().putInt(name,value) 等方法返回的是editor对象,因此可以使用链式编程方法~

               Context.getSharedPreferences(fileName,mode).edit().putInt(name,value).putString(name,value).putBoolean(name,value).apply();


          3. 可以使用Editor putStringSet(String name, Set<String> values)直接存储一个字符串集合

 

          4.使用Secure Preferences(第三方类库)对SharedPreferences中的敏感数据进行加密

                详情-》移步:点击打开链接


          5. 彻底删除sharedPreference文件

              由于创建sharedPreferences时会有一个备份文件,因此仅仅删除pre.xml文件并不能彻底删除,正确的姿势:

              getSharedPreferences().edit().clear().apply();


       6. commit()和apply()区别

           1.返回值

               commit() 返回boolean 用于判断是否提交成功。

               apply() 返回void

           2.失败提示

               apply() 不会提示失败信息

           3. 写入方式

              commit()是同步提交到硬盘,而apply()是先同步写到内存,再异步写入硬盘。在并发提交多个commit时, 而commit需要等前一个写完再进行下一个,而apply是直接更改内存中的,再异步更改硬盘中的,因此apply()在一定程度上效率会更高。

              详情可参照源码进行分析。


             源码建议:

               If you don't care about the return value and you're  using this from your application's main thread, consider using apply instead.

                在应用主线程中,如果你不考虑返回值,那么你可以考虑用apply代替commit。

        源码note: 

        Unlike commit, which writes its preferences out to persistent storage synchronously, apply commits its changes to the in-memory SharedPreferences immediately but starts an asynchronous commit to disk and you won’t be notified of any failures. If another editor on this SharedPreferences does a regular commit while a apply is still outstanding, the commit will block until all async commits are completed as well as the commit itself.


             偶还是小白一枚,欢迎各位指正~ 


  

         


     

 
 

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值