Question

I have a customized EditPreferences that populates the displayed list from a database instead of the default resource XML:

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  addPreferencesFromResource(R.xml.apppreferences);

  ListPreference cityPref = (ListPreference) findPreference(getString(R.string.citypref));

  MySQLiteOpenHelper database = new MySQLiteOpenHelper(context);

  CharSequence[] cities = database.getAllCities();
  cityPref.setEntries(cities);

}

The database is correctly maintained (i.e. the displayed ListPreference shows all entries dynamically added to the database), but when I select one of entries just added, I get an exception:

java.lang.ArrayIndexOutOfBoundsException
    at android.preference.ListPreference.onDialogClosed(ListPreference.java:264)
    at android.preference.DialogPreference.onDismiss(DialogPreference.java:384)
    at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1047)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4627)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    at dalvik.system.NativeStart.main(Native Method)

Apparently something goes out of bound in ListPreference's onDialogClosed():

@Override
protected void onDialogClosed(boolean positiveResult) {
    super.onDialogClosed(positiveResult);

    if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) {
        String value = mEntryValues[mClickedDialogEntryIndex].toString();
        if (callChangeListener(value)) {
            setValue(value);
        }
    }
}

But I don't really want to change the OS's code... Any idea how to work around this problem?

Was it helpful?

Solution

You have to call setEntryValues() as well. Both arrays should have the same size. So simply add a line cityPref.setEntryValues(cities) to your onCreate() method and you should be fine.

By only calling setEntries() both sizes are out of sync. Thus the Exception.

OTHER TIPS

Avoid means you need to cross check the list size and index whether the index which you are trying to access exists or not in the list or even index is greater than the list size.

int entry_size = mEntryValues.length;
if (mClickedDialogEntryIndex < entry_size) {
    String value = mEntryValues[mClickedDialogEntryIndex].toString();
    if (callChangeListener(value)) {
        setValue(value);
    }   
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top