SharedPreferencesCompat的由来与简单解析

最近在读项目源码的时候,发现一个SharedPreferencesCompat类,这个类做了一些简单的工作,后来google之后理解了这种写法的缘由,在这里跟大家分享一下。

首先我们直接来看这个类的源码,很简短

/**
 * Reflection utils to call SharedPreferences$Editor.apply when possible,
 * falling back to commit when apply isn't available.
 */
public class SharedPreferencesCompat {
    private static final Method sApplyMethod = findApplyMethod();

    private static Method findApplyMethod() {
        try {
            Class cls = SharedPreferences.Editor.class;
            return cls.getMethod("apply");
        } catch (NoSuchMethodException unused) {
            // fall through
        }
        return null;
    }

    public static void apply(SharedPreferences.Editor editor) {
        if (sApplyMethod != null) {
            try {
                sApplyMethod.invoke(editor);
                return;
            } catch (InvocationTargetException unused) {
                // fall through
            } catch (IllegalAccessException unused) {
                // fall through
            }
        }
        editor.commit();
    }
}

从上面的代码我们可以看出,首先在

findApplyMethod()

方法里面,我们通过反射获得Editor的apply()对象,这个对象是一个final static,并且findApplyMethod()方法是静态调用的,也就是我们一旦使用了这个类,就首先获得了一个apply()方法对象。

接着,我们看public方法apply(),传入的是一个Editor对象,sApplyMethod不为空,则通过反射调用Editor的apply()方法,否则呢,调用Editor的commit()方法

在这里我们的疑惑是,什么时候sApplyMethod可能为空呢。这里涉及了一个api版本问题,Editor的apply()是在API
9以后新增的,所以为了兼容API 9以下的版本,当我们没有aplly()方法的时候,才调用commit()方法。

OK,说到这里,这个类的作用解决了,但是可能又有一个疑惑,apply()和commit()方法有什么区别呢?

apply()是新增的,目的是为了提高commit()方法的效率问题。

相同点:

1.二者都是提交preference修改数据

2.二者都是原子过程。

区别:

1.apply没有返回值而commit返回boolean表明修改是否提交成功

2.apply是将修改数据原子提交到内存,而后异步真正提交到硬件磁盘;而commit是同步的提交到硬件磁盘,因此,在多个并发的提交commit的时候,他们会等待正在处理的commit保存到磁盘后在操作,从而降低了效率。而apply只是原子的提交到内容,后面有调用apply的函数的将会直接覆盖前面的内存数据,这样从一定程度上提高了很多效率。

3.apply方法不会提示任何失败的提示。

综合上述,由于在一个进程中,sharedPreference是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,建议使用apply,当然需要确保提交成功且有后续操作的话,还是需要用commit的。

commit介绍:public abstract boolean commit ()

修改你的preferences,从Editor到SharePreferences。它执行所请求的修改,替代SharedPreferences中的任何数据

当2个editor同时修改preferences ,最后一个commit成功。

如果不关注返回值或在程序的main线程使用时,推荐使用apply().

apply介绍:public abstract void apply ()

区别:

commit将同步的将数据写到preferences;apply立即更改内存中的SharedPreferences,但是开始异步提交到磁盘中。保存失败你也不会得到任何提示信息,

如果在这个sharedPreferences有另外一个editor执行一个定期的commit,此时一个apply依旧未完成。commit将被阻塞,直到所有异步操作完成,以及自己的commit。

由于SharedPreferences在进程中是单实例的。在忽略返回值的前提下,取代任何实例的commit或apply都是安全的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 16:03:33

SharedPreferencesCompat的由来与简单解析的相关文章

ngx lua模块源码简单解析

ngx lua模块源码简单解析分类: nginx 2014-07-11 11:45 2097人阅读 评论(0) 收藏 举报nginxlua数据结构架构目录(?)[+]对nginx lua模块的整个流程,原理简单解析.由于nginx lua模块相关配置,指令,API非常多,所以本文档只以content_by_lua指令举例说明. 读本文档最好配合读源码. 不适合对nginx和lua一点都不了解的人看.1.相关配置详细配置见 https://github.com/openresty/lua-ngin

对 cloudwu 简单的 cstring 进行简单解析

题外话 以前也用C写过字符串,主要应用的领域是,大字符串,文件读取方面.写的很粗暴,用的凑合着.那时候看见云风前辈的一个开源的 cstring 串. 当时简单观摩了一下,觉得挺好的.也没细看.过了较长一段时间,想整合一下,将大字符串和云风的cstring 短简单的串合在一起变成一种.但是自己 认真复制了一遍后发现. 1.整合不了 云风(后面都省略前辈二字,觉得云风两个字,就已经帅的不行了)简单cstring.因为处理的领域不一样. 云风的 cstring => String , 而自己写的操作文

SQLServer 原理简单解析

(1) 客户端sqlserver网络接口通过一种网络协议(可以是共享内存:简单高速,客户端和sql server在同一台计算机默认连接方式:TCP/IP:访问sql server最常用的一种协议,客户端指定ip地址和端口号连接到sql server;命名管道:命名管道和TCP/IP协议在体系结构上是类似的,是为局域网设计的,在广域网中速度会慢一些:VIA:虚拟接口适配器,是一种可以让两个系统进行高性能通信的协议,要求通信两端使用特殊的硬件和专门连接)和服务的的SNI建立了一个连接,然后通过网络协

ContextImpl简单解析

ContextImpl是对Context的一个具体实现类,关键方法如下 1 static class ServiceFetcher { 2 int mContextCacheIndex = -1; 3 /** 4 * Main entrypoint; only override if you don't need caching. 5 */ 6 public Object getService(ContextImpl ctx) { 7 ArrayList<Object> cache = ctx

iOS开发-简单解析JSON数据

什么是JSON ? JSON是一种轻量级的数据格式,一般用于数据交互 服务器返回给客户端的数据,一般都是JSON格式或者XML格式(文件下载除外) ? JSON的格式很像OC中的字典和数组 ? {"name" : "Jack", "age" : 10} {"name" : ["jack", "rose", "jim"]} ? 标准JSON格式的注意点: key必须用双

[ 转载 ] Java基础10--关于Object类下所有方法的简单解析

关于Object类下所有方法的简单解析 类Object是类层次结构的根类,是每一个类的父类,所有的对象包括数组,String,Integer等包装类,所以了解Object是很有必要的,话不多说,我们直接来看jdk的源码,开始我们的分析之路 1.hashcode() public native int hashCode();//native说明跟机器有关,跟对象的地址有关 如果我们新建一个类,而hashcode没有被重写的话,那么hashcode返回的值只于对象的地址有关,如果hashcode被重

Busybox 简单解析

BusyBox 简单解析 Busybox 作为一个简易的Linux 命令集,因为其小巧简便,在Linux嵌入式系统中应该颇为广泛,人送外号瑞士军刀. Busybox也并非将所有命令的可执行程序进行了打包,对其实现也比较感兴趣,就翻了一下源码. Busybox 工具的使用方式有两种,一种是将命令作为一个参数传入,例如: busybox ls, 而另外一种是将对应的命令直接软连接到busybox BusyBox 实现的核心机制 Busybox的实现依赖于两个点: 通过读取执行程序时传入的参数表,来进

python之urllib2简单解析HTML页面

一.urllib2简单获取html页面 #!/usr/bin/env python # -*- coding:utf-8 -*- import urllib2 response = urllib2.urlopen('http://www.baidu.com'); html = response.read(); print html 简单的几行代码就能拿到html页面,接下来局势html的解析工作了. 想象很美好,实际操作就出问题了.baidu没有禁止机器人抓取可以正常抓取到页面,但是比如:htt

springmvc(2)Controller源码简单解析

前面简单的分析了一下DispatcherServlet,接下来分析一下Controller,在web的MVC中,Controller就是其中的C,启动的一些页面逻辑处理,页面映射的功能: 首先看看超类: public interface Controller {//处理请求,最后返回一个ModelAndView对象,这里的ModelAndView就是我们前面分析过:在DispatchServlet中的doDispath()这个方法里面//会通过render方法得到ModelAndView对象,如