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

    xiaoxiao2021-03-25  17

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

    转载请注明原文地址: https://ju.6miu.com/read-50030.html

    最新回复(0)