How to avoid ArrayIndexOutOfBoundsException in a dynamically updated ListPreference?

StackOverflow https://stackoverflow.com/questions/16705245

  •  30-05-2022
  •  | 
  •  

質問

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?

役に立ちましたか?

解決

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.

他のヒント

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);
    }   
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top