Android 之 SharedPreferences 内部原理浅析

Sharedpreferences 内部工作原理:

  1. 调用getSharedPreferences(); 创建一个SharedPreferences对象,其中会先判断是否存在对应xml文件,如果发现存在则会有一个预加载操作,这个操作是把xml文件的内容通过I/O操作和XmlUitl 解析后存入一个map对象,所以我们调用SharedPreferences::getString();等get操作实际上是不会对文件做I/O操作,而是直接访问刚刚的map集合的内容,这提高了效率,如果对应的xml不存在则重新创建一个对应的xml文件。
@Override
public SharedPreferences getSharedPreferences(String name,int mode){
          SharedPreferences sp;
          //...
          sp=packagePrefs.get(name);
          if(sp==null){
              File prefsFile=getSharedPrefsFile(name);
              //该构造方法会调用startLoadFromDisk();把数据从硬盘加载到内存
            sp =new SharedPreferencesImpl(prefsFile,mode);
            packagePrefs.put(name,sp);
            //...
          return sp;
        }
}
  1. put写操作:写操作也有两步,一是把数据先写入内存中,即map集合,二是把数据写入硬盘文件中。这样才能保证数据的完整性,写操作有两个提交的方式:
    commit():线程安全,性能慢,一般来说在当前线程完成写文件操作。
    apply(): 线程不安全,性能高,异步处理IO操作,一定会把这个写文件操作放入一个 SingleThreadExecutor 线程池中处理
  2. SharedPreferences 在第一次创建后会一直维持一个Singleton, 每次调用getSharedPreferences()都返回唯一的一个实例
SharedPreferences a=getSharedPreferences("test",0);
SharedPreferences b=getSharedPreferences("test",0);
SharedPreferences c=getSharedPreferences("test",0);
Log.i(TAG,"result:"+(a==b)+","+(b==c));
//9-10 09:15:17.810 2287-2287/com.xing.mayapplication l/MainActivity: result:true,true

SharedPreferences 使用封装:

由于SharedPreferences的key 与 value 其实最终都是以String类型存在,所以可以这样写一个SharedPreferences工具类:

/**
* SharedPreferences工具
*/
public class PerferenceManager{
      private static final String PERF_NAME="com.xing_util.perf";
      private static final int CURRENT_VERSION_CODE=1;
      private volatile static PerferenceManager instance;
      private final SharedPreferences preferences;

      private PreferenceManager(Context context){
                  preferences=context.getSharedPreferences(PERF_NAME,Context.MODE_PRIVATE);
                  checkPrefVersion();
      }

      public static PerferenceManager getInstance(Context context){
                if(instance==null){
                  synchronized(PerferenceManager.class){
                          if(instance==null)
                            instance=new PerferenceManager(context);
                   }
                }
                return instance;
      }
       public final void putValue(String key,String value){
              preferences.edit().putString(key,value).apply();
       }
       public final String getValue(String key){
              checkIsLegal(key);
            return preferences.getString(key,"");
       }
       public final void deleteValue(String key){
             checkIsLegal(key);
            preferences.edit().remove(key).apply();
        }
        public final void clear(){
          preferences.edit().clear().apply();
        }
        private void checkIsLegal(String key){
              if(TextUtils.isEmpty(key))
                        throw new IllegalArgumentException("this parameter is illegal,key:"+key);
         }

        private void checkPrefVersion(){
            final int oldVersion=preferences.getInt(PERF_NAME,0);
            if (oldVersion

由于应用版本升级时并不会删除SharedPreferences文件,所以可以加个版本判断,来进行一些数据更新,从上面看来,由于每次调用getSharedPreferences()都会有IO操作,当内容比较多时,那么就不适宜在Application 的onCreate 中进行SharedPreferences 文件初始化了,最好的办法是开个子线程去完成它的创建和数据的预加载!!!

你可能感兴趣的:(Android 之 SharedPreferences 内部原理浅析)