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) {
        SharedPreferencesImpl sp;
//...
            sp = packagePrefs.get(name);
            if (sp == null) {
                File prefsFile = getSharedPrefsFile(name);
                //该构造方法会调用startLoadFromDisk();把数据从硬盘加载到内存
                sp = new SharedPreferencesImpl(prefsFile, mode);
                packagePrefs.put(name, sp);
                return sp;
            }
//...
        return sp;
    }

2、put写操作:写操作也有两步,一是把数据先写入内存中,即map集合,二是把数据写入硬盘文件中。这样才能保证数据的完整性,写操作有两个提交的方式:

commit():线程安全,性能慢,一般来说在当前线程完成写文件操作

apply():线程不安全,性能高,异步处理IO操作,一定会把这个写文件操作放入一个SingleThreadExecutor线程池中处理

3、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));

        //12-04 13:38:17.811 2287-2287/com.sunzxy.myapplication I/MainActivity: result: true,true

SharedPreferences使用封装:

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

/**
 * Created by Sunzxyong on 15/12/4.
 */
public class PerferenceManager {
    private static final String PERF_NAME = "com.suznxyong.util.my_perf";
    private static final int CURRENT_VERSION_CODE = 1;
    private volatile static PerferenceManager instance;
    private final SharedPreferences preferences;

    private PerferenceManager(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 < CURRENT_VERSION_CODE) {
            preferences.edit()
                    .clear()
                    .putInt(PERF_NAME, CURRENT_VERSION_CODE).apply();
        }
    }
}

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

Android之SharedPreferences内部原理浅析的更多相关文章

  1. Git内部原理浅析

    Git独特之处 Git是一个分布式版本控制系统,首先分布式意味着Git不仅仅在服务端有远程仓库,同时会在本地也保留一个完整的本地仓库(.git/文件夹),这种分布式让Git拥有下面几个特点: 1.直接 ...

  2. Android自动化测试框架UIAutomator原理浅析

    UIAutomator是一个Android自动化测试框架,是谷歌在Android4.1版本发布时推出的一款用Java编写的UI测试框架,它只能用于UI即黑盒方面的测试.所以UIAutomator只能运 ...

  3. Android线程管理(三)——Thread类的内部原理、休眠及唤醒

    线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...

  4. jQuery内部原理和实现方式浅析

    这篇文章主要介绍了jQuery内部原理和实现方式浅析,本文试图从整体来阐述一下jQuery的内部实现,需要的朋友可以参考下 这段时间在学习研究jQuery源码,受益于jQuery日益发展强大,研究jQ ...

  5. Android线程管理(三)——Thread类的内部原理、休眠及唤醒

    线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...

  6. Android启动篇 — init原理(二)

    ========================================================          ================================== ...

  7. Android热修复技术原理详解(最新最全版本)

    本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结   通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...

  8. Android FoldingLayout 折叠布局 原理及实现(二)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/44283093,本文出自:[张鸿洋的博客] 1.概述 在上一篇Android Fo ...

  9. JVM 内部原理(四)— 基本概念之 JVM 结构

    JVM 内部原理(四)- 基本概念之 JVM 结构 介绍 版本:Java SE 7 每位使用 Java 的程序员都知道 Java 字节码在 Java 运行时(JRE - Java Runtime En ...

随机推荐

  1. linux系统下安装jdk、tomcat、mysql、redis

    一,安装jdk 1.rpm -qa | grep jdk 检测是否安装jdk 2.rpm -e --nodeps 要卸载的已有jdk名称 3.tar -zxvf jdk-7u71-linux-i586 ...

  2. LintCode题解之最长单词

    这些一次遍历搞定的,套路无非都是在遍历的时候就记录数据的状态,然后根据遍历到的当前的数据的状态来修改最终结果,当遍历完了的时候结果也就确定了. public class Solution { /* * ...

  3. AnyConnect使用说明(手机版)

    一.下载安装客户端 iPhone手机在App Store 里搜索 “Anyconnect”下载安装. Android手机需另外下载Anyconnect. 二. 1.打开AnyConnect,点击&qu ...

  4. Go 错误处理

    Go 语言通过内置的错误接口提供了非常简单的错误处理机制. error类型是一个接口类型,这是它的定义: type error interface { Error() string } 我们可以在编码 ...

  5. 王家林人工智能AI课程大纲和电子书 - 老师微信13928463918

    **3980元团购原价19800元的AI课程,团购请加王家林老师微信13928463918. 基于王家林老师独创的人工智能"项目情景投射"学习法,任何IT人员皆可在无需数学和Pyt ...

  6. 【Java集合系列】---ArrayList

    开篇前言--ArrayList中的基本方法 前面的博文中,小编主要简单介绍java集合的总体架构,在接下来的博文中,小编将详细介绍里面的各个类,通过demo.对比,来对java集合类进行更加深入的理解 ...

  7. 在Spring Boot框架下使用WebSocket实现聊天功能

    上一篇博客我们介绍了在Spring Boot框架下使用WebSocket实现消息推送,消息推送是一对多,服务器发消息发送给所有的浏览器,这次我们来看看如何使用WebSocket实现消息的一对一发送,模 ...

  8. Android自定义View(LimitScrollerView-仿天猫广告栏上下滚动效果)

    转载请标明出处: http://blog.csdn.net/xmxkf/article/details/53303872 本文出自:[openXu的博客] 1分析 2定义组合控件布局 3继承最外层控件 ...

  9. solr多集合配置

    1.1 多SolrCore配置 一个solr工程中可以配置多个SolrCore实例. 分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_ ...

  10. Button的几种常用的xml背景,扁平化,下划线,边框包裹,以及按压效果

    Button的几种常用的xml背景,扁平化,下划线,边框包裹,以及按压效果 分享下我项目中用到的几种Button的效果,说实话,还真挺好看的 一.标准圆角 效果是这样的 他的实现很简单,我们只需要两个 ...