apply与commit有什么区别

还是从源码分析来说明问题:

接上图标记B1处,看下:

所以这个handler发送消息后,handleMessage会被调用看下:


上图提到的Runnable对象是哪个呢??就是enqueueDiskWrite方法里的writeToDiskRunnable对象:

接着分析上图提到的标记C1处:

上上图提到到写完文件操作之后,会调用postWriteRunnable的run来移除任务:

所以对于apply要有一个重要的认识就是:会创建一个子线程来执行写操作,这个子线程是支持消息循环机制的。

这里还有一个疑问就是在上文开始处标记A提到的,为什么入队进行写操作之前要先 QueuedWork.addFinisher(awaitCommit);,而在写操作完成后又调用 QueuedWork.removeFinisher(awaitCommit),关于这一点你可以这么理解:QueuedWork.addFinisher(awaitCommit)可以理解为标记开始写操作状态,QueuedWork.removeFinisher(awaitCommit)则理解为标记写操作结束状态,为何要如此标记呀?要做标记肯定是要给人看的,到底给谁看呢?这里我举一个例子当Activity生命周期要回调onStop的时候,会调用ActivityThread中的handleStopActivity方法,关于这一点你不明白的话可以参考我的文章
Activity生命周期回调是如何被回调的?:

看到上图会调用QueueWork的waitToFinish,而这个方法则是会执行没有完成的写操作,导致主线程被阻塞。所以这里可以得到一个结论apply虽然是另开线程执行写操作,仍然有可能阻塞主线程,上面的例子就是情景之一。如果在Activity Stop的时候,已经写入完毕了,那么万事大吉,不会有任何等待,这个函数会立马返回。但是,如果你使用了太多次的apply,那么意味着写入队列会有很多写入任务,而那里就只有一个线程在写。

如何解决apply导致的ANR问题

下面是头条的方案,主要的原理就是Hook ActivityThread中的Handler 对象,这个handler对象是static,
然后再为这个handler对象设置callback,这样handler会调用callback对象的handleMessage方法,只要我们重写这个callback方法逻辑,就可以跳过原来系统代码,详情参考
头条解决多次调用apply产生ANR的方案

接下来看看commit方法:

到此两个方法都分析完了,做下总结如下:

  • 如果是在主线程直接使用建议使用apply
  • apply和commit都可以导致ANR,apply虽然在处理写文件操作时会在另一个线程来处理,但是多次调用情况下可能导致ANR,而commit则是直接在当前执行文件写操作。

源码分析SharePreferences的apply与commit的区别相关推荐

  1. Spark源码分析:多种部署方式之间的区别与联系

    作者:过往记忆 从官方的文档我们可以知道, Spark 的部署方式有很多种:local.Standalone.Mesos.YARN-..不同部署方式的后台处理进程是不一样的,但是如果我们从代码的角度来 ...

  2. Keras入门笔记(番一):从源码分析K.batch_dot及与dot的区别

    动机 矩阵和向量的乘法各种名称都有,甚至相互混杂,在不同框架里的命名也不一样,每每都会陷入这些Magic中.例如,同样是dot对向量shape= (n,)和一维张量shape=(n,1)而言都不一样, ...

  3. HashMap源码分析-jdk1.6和jdk1.8的区别

    2019独角兽企业重金招聘Python工程师标准>>> 在java集合中,HashMap是用来存放一组键值对的数,也就是key-value形式的数据,而在jdk1.6和jdk1.8的 ...

  4. Dialog源码分析

    目录介绍 1.简单用法 2.AlertDialog源码分析 2.1 AlertDialog.Builder的构造方法 2.2 通过AlertDialog.Builder对象设置属性 2.3 build ...

  5. Snackbar源码分析

    目录介绍 1.最简单创造方法 1.1 Snackbar作用 1.2 最简单的创建 1.3 Snackbar消失的几种方式 2.源码分析 2.1 Snackbar的make方法源码分析 2.2 对Sna ...

  6. android snackbar源码,Snackbar源码分析

    目录介绍 1.最简单创造方法 1.1 Snackbar作用 1.2 最简单的创建 1.3 Snackbar消失的几种方式 2.源码分析 2.1 Snackbar的make方法源码分析 2.2 对Sna ...

  7. JDK源码分析 NIO实现

    总列表:http://hg.openjdk.java.net/ 小版本:http://hg.openjdk.java.net/jdk8u jdk:http://hg.openjdk.java.net/ ...

  8. Django源码分析1:创建项目和应用分析

    django命令行源码分析 本文环境python3.5.2,django1.10.x系列 当命令行输入时django-admin时 (venv) ACA80166:dbManger wuzi$ dja ...

  9. Vuex 2.0 源码分析

    作者:滴滴公共前端团队 - 黄轶 大家好,我叫黄轶,来自滴滴公共前端团队,我们团队最近写了一本书 --<Vue.js 权威指南>,内容丰富,由浅入深.不过有一些同学反馈说缺少 Vuex 的 ...

最新文章

  1. codeforces-73C. LionAge II
  2. Spanning-tree Potocol(整理)
  3. 数据结构与算法之花费铜板最小和利润最大题目
  4. Oracle 4dae,如何处理Python-CXOracle中未知词的错误报告问题,pythoncxOracle,查询,到,生僻字,报错...
  5. 面试中对hashMap的再次理解,负载因子为什么为0.75
  6. 牛客网--华为机试在线训练10:字符个数统计
  7. NFine.Framework框架去除cookie后门方法
  8. CentOS7 部署黑客帝国代码雨
  9. FPGA 入门 (一)
  10. 语义分割系列3-SegNet(pytorch实现)
  11. 表格OCR相关资源整理【ICDAR】【表格识别】【持续更新...】
  12. 替换请求输出文件和日志文件
  13. JavaScript—箭头函数
  14. 非素数模下的二次剩余
  15. 关于sublime Text3 显示gkb乱码的问题
  16. 硬件设计——外围电路(电源电路)
  17. 大学四年如何规划之出国留学
  18. 用易拉罐自制的“蜘蛛音箱”,效果出乎意料
  19. 黑马程序员——Set集合概述及特点
  20. Arm v9“机密计算架构(CCA)” 能实现什么?

热门文章

  1. gradient设置上下渐变_iOS 绘制渐变·实例篇
  2. 相机设置感兴趣区域(自带API)
  3. 业界 | Facebook F8开发者大会首日:扎克伯格走心演讲,VR硬件发售
  4. JavaScript设计模式--简单工厂模式例子---XHR工厂
  5. 关于Java重载方法匹配优先级
  6. Repeater控件最后一笔记录高亮显示
  7. 关于生态、大数据和穿戴设备以及IT创新的畅想
  8. 第拾壹章學習 Lisp 3rd Edition, Winston Horn
  9. 国内做事就要高调——财富人生:邹果庆:中国新蛋网总裁
  10. [转]pthread用于进程间通信