まどろむまどろいど!

日頃のちょっとしたハウツーとかを書きます。まどっちが大好きです。This client is best choise for deep Madorer.

java.lang.~ cannot be cast to java.lang.~ が出る問題の対策

java.lang.○○ cannot be cast to java.lang.●●

が発生する場合,SharedPreferences を使用して作成した xml 内で,既に定義された item の key に 違う型の値を代入しようとしている可能性があり,その場合対象の値を clear(), remove() 等で消去する必要があります.

例えば

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
Editor e = sp.edit();
e.putString("foo", "http://www.foo.com/");
e.putString("bar", true);
e.commit();

とした場合,"パッケージ名.shared_pref.xml" へ

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="foo">http://www.google.com/</string>
<boolean name="bar" value="true" />
</map>

といった具合に値が保存されますが,ここで新たに

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
Editor e = sp.edit();
e.putString("bar", "http://www.foo.com/");
e.Boolean("bar", true);
e.commit();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
Editor e = sp.edit();
e.putBoolean("foo", true);
e.String("bar", "http://www.bar.com/");
e.commit();

等とした場合です.foo, bar は既に String, Boolean な値を所有しているので,ここで新たにそれぞれ Boolean, String を代入しようとすると例外が発生します.また, CheckBoxPreference のようなクラスを使用する際,レイアウト側で

<CheckBoxPreference
    android:key="foo"
    android:defaultValue="true"
    android:title="@string/foo_title"
    android:summaryOn="@string/foo_on"
    android:summaryOff="@string/foo_off" />

と等とすると,チェックボックスを Activity に配置しただけで例外が投げられるので発見が困難な事があります.
何れにしても,

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.edit().remove("foo").commit();

のように clear(), remove() とすると問題なく動作します.