这是 面试系列 的第六期。本期咱们未来探讨一个有趣的东西 —— SharePrefrence 的两种提交方式 apply()
和 commit()
。java
往期内容传递:
Android 面试(一):说说 Android 的四种启动模式
Android 面试(二):如何理解 Activity 的生命周期
Android 面试(三):用广播 BroadcastReceiver 更新 UI 界面真的好吗?
Android 面试(四):Android Service 你真的能应答自如了吗?
Android 面试(五):探索 Android 的 Handler面试
其实很是有趣,咱们常常在开发中使用 SharePrefrence 保存一些轻量级数据,好比判断是不是首次启动,首次启动进入引导页,不然直接到主页面,或者是其它的一些应用场景。微信
而咱们也耳熟能详这样的写法。并发
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()
直接提交的时候会直接报黄色警告。
app
先说说相同点:异步
不一样点直接上源码吧,先看看 commit()
方法的定义:async
/** * 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()
方法的注释也就是两点:ide
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()
不同的地方是,它使用的是异步而不是同步,它会当即将更改提交到内存,而后异步提交到硬盘,而且若是失败将没有任何提示。ui
总结一下不一样点:
commit()
是直接同步地提交到硬件磁盘,所以,多个并发的采用 commit()
作提交的时候,它们会等待正在处理的 commit()
保存到磁盘后再进行操做,从而下降了效率。而 apply()
只是原子的提交到内容,后面再调用 apply()
的函数进行异步操做。apply()
返回值为 void,而 commit()
返回一个 boolean 值表明是否提交成功。apply()
方法不会有任何失败的提示。大多数状况下,咱们都是在同一个进程中,这时候的 SharedPrefrence
都是单实例,通常不会出现并发冲突,若是对提交的结果不关心的话,咱们很是建议用 apply()
,固然须要确保操做成功且有后续操做的话,仍是须要用 commit()
的。