美文网首页
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