CheckBoxPreference是Android Settings常用的控件。CheckBoxPreference的API setDefaultValue(Object)有一个隐藏的功能:在对应的SharedPreference xml文件中插入对应的key/value(如果当前xml文件中没有对应的key/value的情况下)。本文看一下在android框架内部,是如何实现这个功能的。
CheckBoxPreference的继承关系:
CheckBoxPreference extends TwoStatePreference extends Preference

CheckBoxPreference和TwoStatePreference都没有重写setDefaultValue(Object),所以实际上是直接调用Preference.setDefaultValue(Object):

/*** Sets the default value for this Preference, which will be set either if* persistence is off or persistence is on and the preference is not found* in the persistent storage.* * @param defaultValue The default value.*/
public void setDefaultValue(Object defaultValue) {mDefaultValue = defaultValue;
}

可以看到只是用一个成员变量缓存了设置的值。所以持久化并非在这里同步实现的。进一步分析在Preference中成员变量mDefaultValue怎样被使用,看到:

private void dispatchSetInitialValue() {// By now, we know if we are persistent.final boolean shouldPersist = shouldPersist();if (!shouldPersist || !getSharedPreferences().contains(mKey)) {if (mDefaultValue != null) {onSetInitialValue(false, mDefaultValue);}} else {onSetInitialValue(true, null);}
}/*** Implement this to set the initial value of the Preference. * <p>* If <var>restorePersistedValue</var> is true, you should restore the * Preference value from the {@link android.content.SharedPreferences}. If * <var>restorePersistedValue</var> is false, you should set the Preference * value to defaultValue that is given (and possibly store to SharedPreferences * if {@link #shouldPersist()} is true).* <p>* This may not always be called. One example is if it should not persist* but there is no default value given.* * @param restorePersistedValue True to restore the persisted value;*            false to use the given <var>defaultValue</var>.* @param defaultValue The default value for this Preference. Only use this*            if <var>restorePersistedValue</var> is false.*/
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
}

Preference.onSetInitialValue()没做任何事,但在TwoStatePreference中重写了这个方法:

@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {setChecked(restoreValue ? getPersistedBoolean(mChecked): (Boolean) defaultValue);
}/*** Sets the checked state and saves it to the {@link SharedPreferences}.** @param checked The checked state.*/
public void setChecked(boolean checked) {// Always persist/notify the first time; don't assume the field's default of false.final boolean changed = mChecked != checked;if (changed || !mCheckedSet) {mChecked = checked;mCheckedSet = true;persistBoolean(checked);if (changed) {notifyDependencyChange(shouldDisableDependents());notifyChanged();}}
}

CheckBoxPreference没有重写,所以是调用了TwoStatePreference,在这里可以看到实现了持久化。那么就剩下一个问题了,private void Preference.dispatchSetInitialValue()是在什么逻辑下被调用。继续看源代码Preference,只有一处使用dispatchSetInitialValue():

/*** Called when this Preference has been attached to a Preference hierarchy.* Make sure to call the super implementation.* * @param preferenceManager The PreferenceManager of the hierarchy.*/
protected void onAttachedToHierarchy(PreferenceManager preferenceManager) {mPreferenceManager = preferenceManager;mId = preferenceManager.getNextId();dispatchSetInitialValue();
}

CheckBoxPreference作为一个Item被创建出来,一般都会添加到某个PreferenceGroup中,使用API PreferenceGroup.addPreference(Preference):

/*** Adds a {@link Preference} at the correct position based on the* preference's order.* * @param preference The preference to add.* @return Whether the preference is now in this group.*/
public boolean addPreference(Preference preference) {if (mPreferenceList.contains(preference)) {// Existsreturn true;}if (preference.getOrder() == Preference.DEFAULT_ORDER) {if (mOrderingAsAdded) {preference.setOrder(mCurrentPreferenceOrder++);}if (preference instanceof PreferenceGroup) {// TODO: fix (method is called tail recursively when inflating,// so we won't end up properly passing this flag down to children((PreferenceGroup)preference).setOrderingAsAdded(mOrderingAsAdded);}}if (!onPrepareAddPreference(preference)) {return false;}synchronized(this) {int insertionIndex = Collections.binarySearch(mPreferenceList, preference);if (insertionIndex < 0) {insertionIndex = insertionIndex * -1 - 1;}mPreferenceList.add(insertionIndex, preference);}preference.onAttachedToHierarchy(getPreferenceManager());if (mAttachedToActivity) {preference.onAttachedToActivity();}notifyHierarchyChanged();return true;
}

看到这里调用了Preference.onAttachedToHierarchy(),结合前面的分析,可以看到正是这里触发了持久化。

Android CheckBoxPreference设置默认值会触发持久化以及其内部实现逻辑相关推荐

  1. Android Preference 调用setDefaultValue设置默认值不生效;应该使用setValueIndex

    Android Preference 调用setDefaultValue设置默认值不生效:应该使用setValueIndex 如题,希望在ListPreference中设置一个默认值,且不能被设置为其 ...

  2. ajax默认什么方法,ajax设置默认值ajaxSetup()方法

    $(function(){ //设置全局 jQuery Ajax全局参数 $.ajaxSetup({ type:"POST", async:false, cache:false, ...

  3. jpa mysql timestamp_Java JPA设置默认值、Timestamp设置、自动获取时间

    设置默认值 @Column(name="state",columnDefinition="tinyint default 0") private Integer ...

  4. php textarea 默认值,html中的textarea属性大全(设置默认值 高度自适应 获取内容 限制输入字数 placeholder)...

    1.textarea设置默认值 HTML: 此段代码设置一个textarea文本框 并且设置为隐藏 2.textarea高度自适应 今天需要些一个回复评论的页面,设计师给的初始界面就是一个只有一行的框 ...

  5. mysql关于时间的面试题,mysql时间设置默认值MySQL常见面试题

    1.limit(选出10 到20 条) select * from students order by id limit 9,10; 2.MySQL 会使用索引的操作符号 =,>,=,betwe ...

  6. ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数

    ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4  为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift ...

  7. PowerDesigner中如何给字符串字段设置默认值 .

    参考:http://www.cnblogs.com/navy235/archive/2011/10/18/2216443.html 在PowerDesigner12.5中,给varchar或nvarc ...

  8. Elasticsearch 设置默认值的三种方式

    1.实战问题 在使用 Elasticsearch 过程中,不免还会有 Mysql 等关系型数据库的使用痕迹,以下两个都是实战开发问到的问题: Elasticsearch 新增字段,能在 Mapping ...

  9. mysql给字段设置默认值,以及mysql的严格模式

    一.背景 在插入数据库时,报错#1364,后来才知道是字段在创建的时候,没有设置默认值的原因.关于默认值,我们都知道设置默认值为0或者null的时候,就算我们不插入该字段,数据库也会自动按照默认值填充 ...

  10. html5下拉列表默认值,element-ui中的select下拉列表设置默认值方法_简单_前端开发者...

    element-ui中的select下拉列表如何设置默认值? 在element-ui的运用中,涉及到了select下拉列表.项目中需要将select的默认值给展示出来 那如何修改呢? 上element ...

最新文章

  1. wpf 多线程处理同步数据_一文带你理解多线程的实际意义和优势
  2. 虚拟机看服务器mac地址,虚拟机修改服务器mac地址吗
  3. JSP+Servlet基础一
  4. 启程 - 《每日五分钟搞定大数据》
  5. 500分求助,delphi里用standred来配置dbf文件
  6. 无线电能接收初步测试
  7. Python+OpenCV 平移、旋转、缩放、翻转
  8. VC++连接远程Oracle数据库
  9. vue使用@路径引入
  10. 【LeetCode笔记】剑指 Offer 68 - I. 二叉搜索树的最近公共祖先(Java、二叉树、dfs)
  11. python爬虫对炒股有没有用_使用python爬虫实现网络股票信息爬取的demo
  12. 前端例程20211213:网页去色(以灰度形式显示)
  13. VM VirtualBox 安装Window XP3安装版
  14. 西南科技大学OJ题 交换排序算法的设计与实现——冒泡排序1014
  15. 纯前端表格工具使用 - SpreadJS如何将复选框导出Excel
  16. java use g1_深入理解 Java G1 垃圾收集器
  17. 寻路机器人单片机程序示例_单片机c语言示例程序
  18. scrapy 爬虫框架及链家租房信息爬取示例
  19. 开涛老师对Java的全部理解,很透彻。
  20. 【Android】JNI调用(完整版)

热门文章

  1. 华为交换机Console口密码重置及配置
  2. java下载不了_教大家电脑java安装不了怎么办
  3. 腾讯云直播开发日记 (二)附近直播-直播礼物-直播回放
  4. 神经网络求解二阶常微分方程
  5. 开源项目之Windows读取Ext4分区的工具 Ext2Read
  6. Oracle 定时任务执行存储过程
  7. 4款Bootstrap在线富文本编辑器
  8. 【z变换】2. z变换的性质
  9. 南邮的计算机通信工程课程是什么,通信工程考研详解之南京邮电大学
  10. CentOs7下Zabbix安装教程——准备工作