探索Android应用开发(十)

android

android

学习目标:

  1. 解决Preferences崩溃的问题

学习目的:

  1. 掌握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.

4 Comments

Newkey24 3 月, 2011 at 11:55 上午

飘过~Newkey

[…] 详见:http://www.poemcode.net/2009/06/android_develop_10/ […]

[…] 解决Preferences崩溃的问题:java.lang.ClassCastException: java.lang.Integerhttp://www.poemcode.net/2009/06/android_develop_10/ […]

Leave a comment

Your comment