美文网首页
SharePreference 深入原理分析

SharePreference 深入原理分析

作者: 01_小小鱼_01 | 来源:发表于2018-05-06 21:43 被阅读147次
一、简介

SharePreference 是Android 系统中的持久化存储工具其基于XML文件(/data/data/<package name>/shared_prefs/目录下面),一次性将数据读取到内存中,适合单个进程、数据量较小的情况。

二、实践

使用SharedPreferences的正确姿势
1.1 创建SharedPreferences对象

SharedPreferences spf = context.getSharedPreferences("xx",Context.MODE_PRIVATE);
// MODE_PRIVATE,则该配置文件只能被自己的应用程序访问
// MODE_WORLD_READABLE,则该配置文件除了自己访问外还可以被其它应该程序读取
// MODE_WORLD_WRITEABLE,则该配置文件除了自己访问外还可以被其它应该程序读取和写入
// MODE_APPEND,检查文件是否存在,存在就往文件追加内容,否则就创建新文件

1.2 获得SharedPreferences.Editor对象。

SharedPreferences.Editor editor = spf.edit();
editor.putString(key, value);

1.3 插入、删除、查找key-value数据

editor.putString(key, value);
editor.remove(key);
editor.get(key,default-value);
Map<String,?> key_Value=(Map<String, ?>)spf.getAll(); 
// 获取所有保存在对应标识下的数据,并以Map形式返回

1.4 保存key-value数据

editor.apply(); // 异步
editor.commit();  // 同步

三、原理解析

/*
 *xml对应的SharePreferences是否已经被创建加载,如果没有那么该创建就创建,
 *该加载就加载,在加载之后,要将所有的key-value保存到内幕才能中去
 */
public SharedPreferences getSharedPreferences(String name, int mode) {
    SharedPreferencesImpl sp;
    synchronized (ContextImpl.class) {
        if (sSharedPrefs == null) {
            sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
        }

        final String packageName = getPackageName();
        ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
        if (packagePrefs == null) {
            packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
            sSharedPrefs.put(packageName, packagePrefs);
        }
        sp = packagePrefs.get(name);
        if (sp == null) {
            // 读取XML文件
            File prefsFile = getSharedPrefsFile(name);
            sp = new SharedPreferencesImpl(prefsFile, mode);
            // 缓存sp对象
            packagePrefs.put(name, sp);
            return sp;
        }
    }
    
//跨进程同步问题,不推荐使用
    if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
        getApplicationInfo().targetSdkVersion < 
                              android.os.Build.VERSION_CODES.HONEYCOMB) {
        // If somebody else (some other process) changed the prefs
        // file behind our back, we reload it.  This has been the
        // historical (if undocumented) behavior.
        sp.startReloadIfChangedUnexpectedly();
    }
    return sp;
}

SharedPreferencesImpl初始化

// 构造函数传入file 、mode
 SharedPreferencesImpl(File file, int mode) {
    mFile = file;
    mBackupFile = makeBackupFile(file);
    mMode = mode;
    mLoaded = false;
    mMap = null;
    startLoadFromDisk();
}
// 加载XML文件到内存中
private void loadFromDiskLocked() {
   ...
    Map map = null;
    StructStat stat = null;
    try {
        stat = Os.stat(mFile.getPath());
        if (mFile.canRead()) {
            BufferedInputStream str = null;
            try {
    <!--读取xml中配置-->
                str = new BufferedInputStream(
                        new FileInputStream(mFile), 16*1024);
                map = XmlUtils.readMapXml(str);
            }...
    mLoaded = true;
    ...
    <!--唤起其他等待线程-->
    notifyAll();
}
四、总结
  • SharePreferences是Android基于xml实现的一种数据持久化手段
  • SharePreferences不支持多进程,不适合大数据量存储。
  • SharePreferences的commit与apply前者同步方法、后者为异步
参考

1. SharePreference原理及跨进程数据共享的问题

相关文章

网友评论

      本文标题:SharePreference 深入原理分析

      本文链接:https://www.haomeiwen.com/subject/bixprftx.html