Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android custom preference value not saved

Tags:

java

android

I'm trying to get an existing Preference subclass to work that saves a color value. I didn't write the class, but it's supposed to be working on android-7 and above (I'm compiling to an android-9 target.) The full source code is available here. Here's where the preference is saved:

@Override
public void onColorChanged(int color) {
    if (isPersistent()) {
        boolean ret = persistInt(color);
    }
    // (update preview box, other stuff)
}

Using debug output I can tell that isPersistent() returns true, but persistInt() returns false. According to the Android documentation, persistInt() returns whether the preference is persistent; how can these return different values? (Note: setPersistent(true) is explicitly called from the constructor.)

In any case, the value is not saved. A call to getPersistedInt(defaultValue) returns the default value, even later in the same instance of the class. In the code below, getPersistedInt() is always called and always returns mDefaultValue.

public int getValue() {
    try {
        if (isPersistent()) {
            mValue = getPersistedInt(mDefaultValue);
        }
    } catch (ClassCastException e) {
        mValue = mDefaultValue;
    }

    return mValue;
}

Why is this, and how can I make sure the preference is persisted?

like image 998
tmandry Avatar asked Jun 14 '11 22:06

tmandry


Video Answer


1 Answers

After lots of hopeless searching, I finally found the problem: the preference value was not assigned a key, due to a simple typo in my preferences XML file. (I used android.key instead of android:key.)

Since Android doesn't warn you when trying to persist a preference that has no key (but silently fails instead,) you should call the shouldPersist() function instead of isPersistent() before trying to persist a value, and perhaps log a warning if shouldPersist() returns false. For example:

@Override
public void onColorChanged(int color) {
    mValue = color;
    if (shouldPersist()) {
        persistInt(color);
    } else {
        if (isPersistent())
            Log.w("myapp", "shouldPersist() returned false. Check if this preference has a key.");
    }
    // (update preview box, other stuff)
}
like image 82
tmandry Avatar answered Sep 18 '22 19:09

tmandry