Android SharedPreferencesでClassCastExceptionと、一つのkeyに二つの型を保存できるのか?を調べる
SharedPreferences を使った記事の続き。
前回の記事↓
SharedPreferences で
まだ調べ足りないことがあったので
2点ほど調査する。
保存した型と違う型を取得
そりゃダメだよねって明らかに分かる
違う型を取得するパターンだが、一応記載。
下記の実装では
String で保存したのに
boolean を取得しようとしている。
取得時 ClassCastException が吐き出される
| java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean |
PreferenceUtil.java
public class PreferenceUtil {
enum PreferenceKey {
KEY_STRING,
KEY_BOOLEAN,
}
// Stringを保存
public static void putString(Context context, PreferenceKey key, String value) {
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = pref.edit();
editor.putString(key.name(), value);
editor.apply();
}
// booleanを保存
public static void putBoolean(Context context, PreferenceKey key, boolean value) {
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
editor.putBoolean(key.name(), value);
editor.apply();
}
// Stringを取得
public static String getString(Context context, PreferenceKey key) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getString(key.name(), "");
}
// booleanを取得
public static boolean getBoolean(Context context, PreferenceKey key) {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(key.name(), false);
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// KEY_STRINGで適当な文字列を保存する
PreferenceUtil.putString(getApplicationContext(),
PreferenceUtil.PreferenceKey.KEY_STRING, "文字列を保存");
Button button = findViewById(R.id.button);
button.setOnClickListener(view -> {
// KEY_STRINGでbooleanを取得しようとするが
// 保存した値の型が違うのでgetできない
boolean bool = PreferenceUtil.getBoolean(
getApplicationContext(), PreferenceUtil.PreferenceKey.KEY_STRING);
Toast.makeText(this, "Boolean:" + bool, Toast.LENGTH_LONG).show();
});
}
}
1つのkeyに2つの型を保存できる?
結論
結論から言うと
2つの型を同時に持つことはできない。
KEY_BOOLEAN という key があった時
① KEY_BOOLEAN に boolean を保存
② KEY_BOOLEAN に String を保存
の順序で処理すると
KEY_BOOLEAN で取得できるのは String となる
つまり
最後に処理した型が保存される
(後勝ちで上書かれる)
検証
先ほどの PreferenceUtilクラス はそのままで
MainActivity の処理を変えて検証してみる。
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ① KEY_BOOLEANにbooleanを保存する
PreferenceUtil.putBoolean(getApplicationContext(),
PreferenceUtil.PreferenceKey.KEY_BOOLEAN, true);
// ② KEY_BOOLEANにStringを保存する
PreferenceUtil.putString(getApplicationContext(),
PreferenceUtil.PreferenceKey.KEY_BOOLEAN, "keyにbooleanってあるけどいいの?");
Button button = findViewById(R.id.button);
button.setOnClickListener(view -> {
/*
// 最後に保存したのがStringなのでClassCastExceptionになる
boolean bool = PreferenceUtil.getBoolean(
getApplicationContext(), PreferenceUtil.PreferenceKey.KEY_BOOLEAN);
*/
// Stringは問題なく取得できる
String str = PreferenceUtil.getString(
getApplicationContext(), PreferenceUtil.PreferenceKey.KEY_BOOLEAN);
Toast.makeText(this, str, Toast.LENGTH_LONG).show();
});
}
}
①で保存した型である boolean は
String に上書きされていることが分かる。
まとめ
一つの key に2つの型を保存
という行為そのものをしたことがなかったので
いい勉強になった。
もっと便利に使うなら
オブジェクトを json にして保存ができるから
今度はそこらへんをまとめてみよう。

ディスカッション
コメント一覧
まだ、コメントがありません