探索Android应用开发(十)
学习目标:
- 解决Preferences崩溃的问题
学习目的:
- 掌握ListPreference的使用
学习收获:
Android在android.preference提供了多种preference,但是令人感到遗憾的是,其没有提供一个单选按钮,就像是HTML中的radio button一样,多个选项为一组,每次只能选择其中一个。不过,Android提供了ListPreference,展现一个列表,让人选择列表项,间接达到了“只选其一”的效果。
ListPreference的XML属性中有两个重要属性:android:entries和android:entryValues,也就是说只需要定义两个数组,就可以快速构建一个ListPreference,用户看的是enties,程序实际返回的是entryValues。于是在arrays.xml中,定义如下两个数组:
<resources> <string-array name="ver_count_entry_text"> <item>two</item> <item>three</item> <item>four</item> <item>five</item> </string-array> <integer-array name="ver_count_entry_value"> <item>2</item> <item>3</item> <item>4</item> <item>5</item> </integer-array> </resources> |
然后定义对应的PrefenceScrean的XML文件,如下:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <ListPreference android:key="@string/setting_ver_count_key" android:title="@string/setting_ver_count_title" android:entries="@array/ver_count_entry_text" android:entryValues="@array/ver_count_entry_value" android:persistent="true" /> </PreferenceScreen> |
程序第一次运行后,看到保存后的xml文件:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <map> <int name="ver_count" value="3" /> <int name="hor_count" value="3" /> </map> |
很不错,我们已经把值保存进了preferences中,但是问题随后就来了,当第二次启动的时候,PreferenceActivity在onCreate方法中,执行this.addPreferencesFromResource(R.xml.setting),android马上报错,程序停止执行,错误信息如下:
Caused by: java.lang.ClassCastException: java.lang.Integer at android.app.ApplicationContext$SharedPreferencesImpl.getString(ApplicationContext.java:2535) at android.preference.Preference.getPersistedString(Preference.java:1242) at android.preference.ListPreference.onSetInitialValue(ListPreference.java:232) at android.preference.Preference.dispatchSetInitialValue(Preference.java:1165) at android.preference.Preference.onAttachedToHierarchy(Preference.java:984) at android.preference.PreferenceGroup.addPreference(PreferenceGroup.java:156) at android.preference.PreferenceGroup.addItemFromInflater(PreferenceGroup.java:97) at andaoid.preference.PreferenceGroup.addItemFromInflater(PreferenceGroup.java:38) at android.preference.GenericInflater.rInflate(GenericInflater.java:488) at android.preference.GenericInflater.inflate(GenericInflater.java:326) at android.preference.GenericInflater.inflate(GenericInflater.java:263) at andaoid.preference.PreferenceManager.inflateFromResource(PreferenceManager.java:250) at android.preference.PreferenceActivity.addPreferencesFromResource(PreferenceActivity.java:253) at net.poemcode.jigsaw.SettingActivity.onCreate(SettingActivity.java:27) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231) ... 11 more |
很明显是发生了转型错误,有代码要把Integer转化成String,结果出错了,那么为什么会出错呢?
打开android的源码,在ApplicationContext.java文件,找到出错的方法:
public String getString(String key, String defValue) { synchronized (this) { String v = (String)mMap.get(key); return v != null ? v : defValue; } } |
此时问题揭开了谜团,原来这个方法只认String,而此前我们保存的值是Integer,所以就无法转型,这是导致问题的直接原因。可是又有一个疑问,为什么是Integer就不支持了?实际应用中,难道我们保存preferences为数值型就不行吗?
顺着出错信息,找到了ListPreference的代码,真相出现了,原来ListPreference定义的value类型是String,也就是说ListPreference的value只能是String。而我在保存preferences时,采用的是如下的方式:
public static void writeBack() { Editor editor = mSharedPref.edit(); editor.putInt(horCountKey, HOR_COUNT); editor.putInt(verCountKey, VER_COUNT); editor.commit(); } |
这真是件让人抓狂的事情!回过头来,再看ListPreference的API文档,里面赫然写着:
This preference will store a string into the SharedPreferences. This string will be the value from the setEntryValues(CharSequence[]) array.
飘过~Newkey
[…] 详见:http://www.poemcode.net/2009/06/android_develop_10/ […]
[…] http://www.poemcode.net/2009/06/android_develop_10/“>http://www.poemcode.net/2009/06/android_develop_10/ […]
[…] 解决Preferences崩溃的问题:java.lang.ClassCastException: java.lang.Integerhttp://www.poemcode.net/2009/06/android_develop_10/ […]