从源码角度分析sharedPreferences的commit()与apply()的区别
来源:互联网 发布:mac 更改用户照片 编辑:程序博客网 时间:2024/05/22 03:12
对于Android开发者来说,对于sharedPreferences并不陌生,用于存储轻量级的数据,而存储的时候,会用到Editor,在API 9之前,提交的时候用用到了editor.commit()方法,而从API 9之后,新增了一个apply()方法,可能大家多多少少知道它是一个异步的提交,能提高IO性能。
而本篇文章主要就是从源码去分析,它是如何提高IO性能的。废话不多说,上代码,跟进代码大家看到,sharedPreferences只是一个接口,所有的实现逻辑都在它的实现类sharedPreferencesImpl里,首先看下commit()方法,看代码解释:
public boolean commit() { MemoryCommitResult mcr = commitToMemory();//把数据提交到内存 SharedPreferencesImpl.this.enqueueDiskWrite( mcr, null /* sync write on this thread okay */); try { mcr.writtenToDiskLatch.await(); } catch (InterruptedException e) { return false; } notifyListeners(mcr); return mcr.writeToDiskResult; }
public void apply() { final MemoryCommitResult mcr = commitToMemory();//把数据提交到内存 final Runnable awaitCommit = new Runnable() { public void run() { try { mcr.writtenToDiskLatch.await(); } catch (InterruptedException ignored) { } } }; QueuedWork.add(awaitCommit); Runnable postWriteRunnable = new Runnable() { public void run() { awaitCommit.run(); QueuedWork.remove(awaitCommit); } }; SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable); // Okay to notify the listeners before it's hit disk // because the listeners should always get the same // SharedPreferences instance back, which has the // changes reflected in memory. notifyListeners(mcr); }
比较两个方法,首先都是先把数据同步提交到内存中,然后再执行下面的SharedPreferencesImpl.this.enqueueDiskWrite方法,而两个方法调用不同的地方是,commit第二个参数传进去是null,apply传进去的是postWriteRunnable。咱们看下enqueueDiskWrite()这个方法里面是怎么执行的。
private void enqueueDiskWrite(final MemoryCommitResult mcr,final Runnable postWriteRunnable) { final Runnable writeToDiskRunnable = new Runnable() { public void run() { synchronized (mWritingToDiskLock) { writeToFile(mcr); } synchronized (SharedPreferencesImpl.this) { mDiskWritesInFlight--; } if (postWriteRunnable != null) { postWriteRunnable.run(); } } }; final boolean isFromSyncCommit = (postWriteRunnable == null); // Typical #commit() path with fewer allocations, doing a write on // the current thread. if (isFromSyncCommit) { boolean wasEmpty = false; synchronized (SharedPreferencesImpl.this) { wasEmpty = mDiskWritesInFlight == 1; } if (wasEmpty) { writeToDiskRunnable.run(); return; } } QueuedWork.singleThreadExecutor().execute(writeToDiskRunnable); }
首先这个方法里先new 一个Runnable writeToDiskRunnable (注意这里,只是一个Runnbale,而不是new Thread/一个子线程,有部分同学可能看到Runnable以为就是一个子线程呢),然后这个writeToDiskRunnable的run方法里执行writeToFile的方法,就是正在的要写到sp文件的方法了。接着往下看,isFromSyncCommit变量,它就是跟着commit与apply传进来的postWriteRunnable是否为空判断的,所以这当是commit方法调用是,isFromSyncCommit为true,apply方法调用时,isFromSyncCommit为false,所以当isFromSyncCommit为true并且mDiskWritesInFlight为1时(commitToMemory赋值的),就在当前的线程里执行了writeToDiskRunnable 的writeToFile方法了,也就是说当commit()方法调用的时候,是在当前线程执行的,串行执行。当apply()方法调用的时候,直接把writeToDiskRunnable 添加到QueuedWork.singleThreadExecutor().execute(writeToDiskRunnable);队列中执行,也就是异步执行,所以说apply相对commit能提交IO性能。
好了,以上就是自己从源码角度去分析SharedPreferences的commit与apply区别,如有写不对的地方,欢迎各位指正,多谢!
- 从源码角度分析sharedPreferences的commit()与apply()的区别
- SharedPreferences.Editor 的commit方法与apply方法的区别
- Android中SharedPreferences的apply()与commit()的区别
- SharedPreferences 的commit和apply分析
- android SharedPreferences apply和commit的区别
- SharedPreferences中commit和apply的区别
- SharedPreferences commit跟apply的区别
- SharedPreferences的commit和apply
- SharePreferences源码分析(commit与apply的区别以及原理)
- SharePreferences源码分析(commit与apply的区别以及原理)
- SharePreferences源码分析(commit与apply的区别以及原理)
- SharedPreferences.Editor的apply和commit方法区别
- SharePreference的commit与apply的区别
- 从源码的角度分析Hashtable和HashMap的区别
- commit和apply的区别
- 从Java源码的角度来分析HashMap与HashTable的区别
- 从源码的角度分析,getWidth() 与 getMeasuredWidth() 的不同之处
- SharedPreference提交的commit与apply的区别
- Linux 进程
- Android Wi-Fi wifi scan流程分析(Android 7.0)
- hdu2063 过山车【二分图匹配】
- 并发编程中的CAS算法
- 近邻分析 -- KNN
- 从源码角度分析sharedPreferences的commit()与apply()的区别
- Qt国际化实时切换
- 使用IDEA创建Gradle项目整合SSM框架
- 创建ssm项目
- 方法
- tomcat启动https的配置
- 数据库入门---增删改查
- 【剑指offer】二叉树的深度
- 使用sqoop导入导出mysql、hdfs、hive出现的问题