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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值