2013-04-10 13 views
8

フラグメントのライフサイクル全体にわたって保存したい状態がいくつかあります。例えば、画面が回転しても問題なく動作しますが、プロセスが強制終了されてディスクから復元されたとき(私はそれが動作すると思います)、ClassCastExceptionを取得します。 ここにいくつかのコードです:Androidでバンドルからデータを取得するときにClassCastExceptionが発生する

初期化:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (savedInstanceState == null) { 
     playlistsMap = new LinkedHashMap<Section, List<Playlist>>(); 
    } else { 
     playlistsMap = (LinkedHashMap<Section, List<Playlist>>) savedInstanceState.getSerializable(PLAYLISTS_MAP_KEY); 
    } 
    setHasOptionsMenu(true); 
} 

セーブデータ:

@Override 
public void onSaveInstanceState(Bundle outState) { 
    if (isEverySectionsLoaded()) { 
     outState.putSerializable(PLAYLISTS_MAP_KEY, playlistsMap); 
    } else { 
     outState.putSerializable(PLAYLISTS_MAP_KEY, new LinkedHashMap<Section, List<Playlist>>()); 
    } 
    // ... 
} 

私はonCreateにキャストから取得する例外:

04-10 01:06:43.430 E/AndroidRuntime(28549): FATAL EXCEPTION: main 
04-10 01:06:43.430 E/AndroidRuntime(28549): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mydomain.android/com.mydomain.android.ui.MainActivity}: 
java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap 

私はそれが良いでしょう知っているが、 Androidでパーセルブルを使用することはできますが、まだ理解していませんそれがどうして起こるか?

アイデア?

+0

私の場合、HashtableはsavedInstanceStateに保存されています。画面を回転させると、ハッシュテーブルが取得されますが、アプリがクラッシュした場合は、前述のとおり、ハッシュマップが取得され、クラスキャスト例外が発生します。あなたはこれに対して良い解決策または回避策を見つけることができましたか? – Nil

答えて

11

興味深いリードhere

java.util.Listに及びjava.io.Serializableの両方がintent.putExtra(EXTRA_TAG、 suchObject)後 ArrayListになるであろう実装するオブジェクト見出すことができます/ startActivity(intent)/intent.getSerializableExtra(EXTRA_TAG)。

私は、シリアライザブルとマップを実装しているものはどれも同じであると言います。そのHashMapがデフォルトに戻ります。

バグに似たものになるだろうように思えるこの周りソリューション:

private LinkedHashMap<Section, List<Playlist>> playlistsMap; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (savedInstanceState == null) { 
     playlistsMap = new LinkedHashMap<Section, List<Playlist>>(); 
    } else { 
     //assuming the bug returns a hashmap 
     Map<Section, List<Playlist>> items = (Map<Section, List<Playlist>>) savedInstanceState.getSerializable(PLAYLISTS_MAP_KEY); 

     //this way you can ensure you are working with a linkedHashMap. 
     //for the rest off the application 
     playlistsMap.putAll(items); 
    } 
    setHasOptionsMenu(true); 
} 

上記のコードがテストされていませんが、動作するはずですが。 このコードは、インターフェイスの使用によりバグが修正された場合でも動作します。 あなたのクライアントがアンドロイドの更新を取得して、クラッシュせずにHashMapをLinkedHashMapにキャストできないというコードでも、同じコードを実行する必要がある場合は、安心できます。

+0

はい、私はLinkedHashMapとHashMapが互換性がないことを知っています、私はHashMapがどこから来ているのか分かりません。 putSerializable/getSerializableメソッドは、Serializableを実装しているという事実から離れていることを知っているとは思われません。 – kombucha

+0

Mmhmは、アンドロイドライブラリ自体のバグかもしれません。私はあなたと同様の問題を抱えている人々の多くを読んだ。私はまだ "なぜ"の答えを見つける必要があります。あなたがもっと見つけたら、私は見続けて、あなたに知らせてください。一時的な解決策として、マップにキャストすることができます。それは、HashMapにキャストすることに不満があるなら、うまくいくはずです –

+0

私の答えをリンクで編集しました。それは面白い読み物かもしれません。 –

-2

問題は、返されたリファレンスが単にLinkedHashMapのインスタンスへの参照ではないということです。関数Return LinkedHashMapがちょうどLinkedHashMapを返した場合、それはHashMapにキャストできません。同様の問題に関する

+0

クラスキャストの例外が意味するものは分かりますが、どこから来ているのか分かりません。私はSerializableとしてバンドルにLinkedHashMapを置いています。私はbundle.getSerializableが私に同じオブジェクトを返すことを期待しています。 – kombucha

+0

ここで、LinkedHashMap –

+0

を取得し、それをHashMapに渡します。 –

関連する問題