SharedPreferences commit跟apply的区别

大多数人在二十岁或三十岁就死了,他们变成了自己的影子,往后的生命只是不断的一天天复制自己。——罗曼·罗兰《约翰•克里斯多夫》

SharedPreferences的commit跟apply方法的区别。平时用到的时候只是习惯性的选中apply方法,其中具体的区别没有深究,是时候看看源码一探究竟了。

commit方法

先看看原汁原味的源码解释

/**
* Commit your preferences changes back from this Editor to the
* {@link SharedPreferences} object it is editing.  This atomically
* performs the requested modifications, replacing whatever is currently
* in the SharedPreferences.
*
* <p>Note that when two editors are modifying preferences at the same
* time, the last one to call commit wins.
*
* <p>If you don't care about the return value and you're
* using this from your application's main thread, consider
* using {@link #apply} instead.
*
* @return Returns true if the new values were successfully written
* to persistent storage.
*/
boolean commit();

从源码解释看commit方法有下面的特点

  • 存储的过程是原子操作
  • commit方法有返回值,设置成功为ture,否则为false
  • 同时对一个SharedPreferences设置值最后一次的设置会直接覆盖前次值
  • 如果不关心设置成功与否,并且是在主线程设置值,建议用apply方法

apply方法

/**
* Commit your preferences changes back from this Editor to the
* {@link SharedPreferences} object it is editing.  This atomically
* performs the requested modifications, replacing whatever is currently
* in the SharedPreferences.
*
* <p>Note that when two editors are modifying preferences at the same
* time, the last one to call apply wins.
*
* <p>Unlike {@link #commit}, which writes its preferences out
* to persistent storage synchronously, {@link #apply}
* commits its changes to the in-memory
* {@link SharedPreferences} immediately but starts an
* asynchronous commit to disk and you won't be notified of
* any failures.  If another editor on this
* {@link SharedPreferences} does a regular {@link #commit}
* while a {@link #apply} is still outstanding, the
* {@link #commit} will block until all async commits are
* completed as well as the commit itself.
*
* <p>As {@link SharedPreferences} instances are singletons within
* a process, it's safe to replace any instance of {@link #commit} with
* {@link #apply} if you were already ignoring the return value.
*
* <p>You don't need to worry about Android component
* lifecycles and their interaction with <code>apply()</code>
* writing to disk.  The framework makes sure in-flight disk
* writes from <code>apply()</code> complete before switching
* states.
*
* <p class='note'>The SharedPreferences.Editor interface
* isn't expected to be implemented directly.  However, if you
* previously did implement it and are now getting errors
* about missing <code>apply()</code>, you can simply call
* {@link #commit} from <code>apply()</code>.
*/
void apply();

apply特点如下

  • 存储的过程也是原子操作
  • apply没有返回值,存储是否成功无从知道。
  • apply写入过程分两步,第一步先同步写入内存,第二部在异步写入物理磁盘。并且写入的过程会阻塞同一个SharedPreferences对象的其他写入操作。

原子操作的意思是”不可中断的一个或一系列操作”,通俗的讲一个操作一旦开始,在结束前不会被打断。比如常见的++i操作就不具有原子性,因为它实际上包含了3个步骤,1-读取i的值,2-对读取的i值加1,3-写入加1后的值。单独看此三个步骤都是原子操作,但组合起来就是非原子操作了。

总结

commit相对与apply效率较低,commit直接是向物理介质写入内容,而apply是先同步将内容提交到内存,然后在异步的向物理介质写入内容。这样做显然提高了效率。

    原文作者:小草凡
    原文地址: https://www.jianshu.com/p/790510b29efe
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞