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

来源:互联网 发布:网络弱电系统图图解 编辑:程序博客网 时间:2024/05/17 22:10
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中重写了这个方法:

@Overrideprotected 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)) {        // Exists        return 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(),结合前面的分析,可以看到正是这里触发了持久化。

1 0
原创粉丝点击