tags:

views:

196

answers:

1

Seems like I must be doing something basic very wrong, but the results are strange, and I'm having trouble tracking the problem down.

This is in my my Activity's onCreate()

PreferenceManager.setDefaultValues(this, R.xml.metronome_preferences, false);
mSharedPrefs=PreferenceManager.getDefaultSharedPreferences(this);

The following code lives in onStart().

Map<String,?> map = mSharedPrefs.getAll();
boolean t = mSharedPrefs.contains("tempo_list_pref");
Log.d(logID, "t= " + t + " preferences=" + map.toString());
mBPMOption = mSharedPrefs.getLong("tempo_list_pref", 100);

Log cat correctly shows:

02-05 11:14:27.605: DEBUG/Metronome(16147): t=true preferences={graphics_list_pref=1, conduct_list_pref=12.0f, tempo_list_pref=140, audio_list_pref=2, meter_list_pref=5}

mBPMOption is a long. The shared prefs object is apparently valid as I can both retrieve the preferences as a map, and test for the presence of a preferences, but the call to getLong() causes ClassCastExceptions to be recursively thrown. At least, that's how I'm interpreting what I'm seeing in the debugger. The error object e contains e.cause, e.cause.cause, ... .

I'm getting this same error in the emulator and on the Google ION dev phone.

Any thoughts on this would be appreciated.

A: 

it would help if you showed the stack trace, but...

private static final class SharedPreferencesImpl implements SharedPreferences {
    ...
    public long getLong(String key, long defValue) {
        synchronized (this) {
            Long v = (Long) mMap.get(key);
            return v != null ? v : defValue;
        }
    }

10p says your ClassCastException is being thrown there. when the documentation says getLong will throw ClassCastException isn't a Long, it really means it: an int won't do. are you sure you stored this as a long? adding this line to your code will tell you what you've got:

System.err.println(map.get("tempo_list_pref").getClass());
Elliott Hughes
Great suggestion! Turns out that all of my numeric resources exist in the map as strings, which is consistent with my workaround. I'm just using the appropriate decode() or parseFloat() static methods on the values in the map. If the Android internal preference map only contains string values, it seems to me that the Android code should read:Long v = Long.decode((String)map.get(key));
Mark