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 にして保存ができるから
今度はそこらへんをまとめてみよう。
ディスカッション
コメント一覧
まだ、コメントがありません