Android 面试(六):你已经用 SharedPrefrence 的 apply() 替换 commit() 了吗?
这是 面试系列 的第六期。本期我们将来探讨一个有趣的东西 —— SharePrefrence 的两种提交方式 apply()
和 commit()
。
往期内容传递:
Android 面试(一):说说 Android 的四种启动模式
Android 面试(二):如何理解 Activity 的生命周期
Android 面试(三):用广播 BroadcastReceiver 更新 UI 界面真的好吗?
Android 面试(四):Android Service 你真的能应答自如了吗?
Android 面试(五):探索 Android 的 Handler
开始
其实非常有趣,我们经常在开发中使用 SharePrefrence 保存一些轻量级数据,比如判断是否是首次启动,首次启动进入引导页,否则直接到主页面,或者是其它的一些应用场景。
而我们也耳熟能详这样的写法。
- 根据 Context 获取 SharedPreferences 对象
- 利用 edit() 方法获取 Editor 对象。
- 通过 Editor 对象存储 key-value 键值对数据。
- 通过 commit() 方法提交数据。
public class SplashActivity extends AppCompatActivity { public static final String SP_KEY = "com.zxedu.myapplication.SplashActivity_SP_KEY"; public static final String IS_FIRST_IN = "com.zxedu.myapplication.SplashActivity_IS_FIRST_IN"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 一些业务代码 ...... SharedPreferences preferences = getSharedPreferences("name",MODE_PRIVATE); if (preferences.getBoolean(IS_FIRST_IN,true)){ // 跳转引导页面 startActivity(new Intent(this,GuideActivity.class)); finish(); }else{ // 跳转主页面 startActivity(new Intent(this,MainActivity.class)); } } } public class GuideActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); getSharedPreferences(SplashActivity.SP_KEY,MODE_PRIVATE).edit().putBoolean(SplashActivity.IS_FIRST_IN,false).apply(); } }
从代码中可以看到,一阵混乱操作,没啥特别的地方,但早期开发的人员应该知道,之前我们都是比较青睐 commit()
进行提交的。而现在 Android Studio 在我们使用 commit()
直接提交的时候会直接报黄色警告。
commit() 和 apply() 到底有什么异同?
先说说相同点:
- 二者都是提交 Prefrence 修改数据;
- 二者都是原子过程。
不同点直接上源码吧,先看看 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()
方法的注释也就是两点:
- 会返回执行结果。
- 如果不考虑结果并且是在主线程执行可以考虑
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()
跟 commit()
不一样的地方是,它使用的是异步而不是同步,它会立即将更改提交到内存,然后异步提交到硬盘,并且如果失败将没有任何提示。
总结一下不同点:
-
commit()
是直接同步地提交到硬件磁盘,因此,多个并发的采用commit()
做提交的时候,它们会等待正在处理的commit()
保存到磁盘后再进行操作,从而降低了效率。而apply()
只是原子的提交到内容,后面再调用apply()
的函数进行异步操作。 - 翻源码可以发现
apply()
返回值为 void,而commit()
返回一个 boolean 值代表是否提交成功。 -
apply()
方法不会有任何失败的提示。
那到底使用 commit() 还是 apply()?
大多数情况下,我们都是在同一个进程中,这时候的 SharedPrefrence
都是单实例,一般不会出现并发冲突,如果对提交的结果不关心的话,我们非常建议用 apply()
,当然需要确保操作成功且有后续操作的话,还是需要用 commit()
的。
做不完的开源,写不完的矫情。欢迎扫描下方二维码或者公众号搜索「nanchen」关注我的微信公众号,目前多运营 Android ,尽自己所能为你提升。如果你喜欢,为我点赞分享吧~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
iOS :学习新技术途径和sizeClasses屏幕适配
1.了解有什么新技术 1>苹果API文档- General - Guides - iOSx API Diffs 2>观看WWDC会议视频 2.如何使用新技术 1>自己根据API文档尝试新的类和新的方法 2>百度:iOSx开发 3>苹果API文档- xxx - SampleCode *比如Cocoa Touch Layer - UIKit 4> github网站:搜索新技术新代码,比如搜索Presentation 3.推荐学习网站 1>个人博客:技术大牛 唐巧:http://blog.devtang.com/blog/archives/ 王巍:http://www.onevcat.com 破船之家:http://beyondvincent.com 池建强:http://www.cnblogs.com/chijianqiang/ 2>社区博客 CocoaChina:http://www.cocoachina.com Code4App:http://www.code4app.com 伯乐在线:http://blog.jobbole.com ...
- 下一篇
《从零开始学Swift》学习笔记(Day 18)——有几个分支语句?
分支语句又称条件语句,Swift编程语言提供了if、switch和guard三种分支语句。 if语句 由if语句引导的选择结构有if结构、if-else结构和else-if结构3种。 if结构示例代码如下: 1 2 3 4 5 varscore= 95 if score>= 85 { print( "您真优秀!" ) } 程序运行结果如下: 您真优秀! if-else结构示例代码如下: 1 2 3 4 5 6 7 varscore= 95 if score< 60 { print( "不及格" ) } else { print( "及格" ) } 程序运行结果如下: 及格 else-if结构示例代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 lettestscore= 76 vargrade:Character if testscore>= 90 { grade= "A" } else if testscore>= 80 { grade= "B" } else if testscore>= 70 {...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7设置SWAP分区,小内存服务器的救世主
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Hadoop3单机部署,实现最简伪集群
- Mario游戏-低调大师作品
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Red5直播服务器,属于Java语言的直播服务器