[英]ClassCastException when retrieving data from bundle on Android
I have some state that I want to save accross the lifecycle of a fragment. 我有一些状态,我想在片段的生命周期中保存。 It works fine when the screen rotates for example, but when the process has been killed and restored from disk (I think that's how it works), I get a ClassCastException.
例如,当屏幕旋转时,它工作正常,但是当从磁盘中杀死并恢复进程时(我认为它是如何工作的),我得到一个ClassCastException。 Here's some code:
这是一些代码:
Initialization: 初始化:
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);
}
Saving the data : 保存数据:
@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>>());
}
// ...
}
The exception I get from the cast in onCreate
: 我从
onCreate
中的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
I know it's better to use parcelables on Android, but I still don't understand how that could ever happen. 我知道在Android上使用parcelables会更好,但我仍然不明白这是怎么回事。
Any ideas? 有任何想法吗?
Interesting read concerning a similar question can be found here 有关类似问题的有趣读物可以在这里找到
Any object that implements both java.util.List and java.io.Serializable will become ArrayList after intent.putExtra(EXTRA_TAG, suchObject)/startActivity(intent)/intent.getSerializableExtra(EXTRA_TAG).
任何实现java.util.List和java.io.Serializable的对象都将在intent.putExtra(EXTRA_TAG,suchObject)/ startActivity(intent)/intent.getSerializableExtra(EXTRA_TAG)之后变为ArrayList。
I dare to say that the same counts for anything that implements serializable and map. 我敢说同样重要的是实现可序列化和映射的任何东西。 That HashMap is the default you will get back.
HashMap是您将获得的默认值。
A solution around this what seems like a bug would be something similar to: 围绕这个似乎是一个bug的解决方案将类似于:
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);
}
The above code isn't tested but should work. 上面的代码没有经过测试但应该可行。 This code will still work when the bug gets fixed due to the usage of interfaces.
由于接口的使用,当错误得到修复时,此代码仍然有效。 So you can rest assured when your client gets an android update that your code should still do the same instead of crashing and complaining that you cant cast a HashMap to a LinkedHashMap.
因此,您可以放心,当您的客户端获得一个Android更新时,您的代码应该仍然执行相同而不是崩溃并抱怨您无法将HashMap强制转换为LinkedHashMap。
The problem is that the reference returned simply isn't a reference to an instance of LinkedHashMap
. 问题是返回的引用不是对
LinkedHashMap
实例的引用。 If function Return LinkedHashMap
just returns a LinkedHashMap
, it can't be cast to HashMap. 如果函数Return
LinkedHashMap
只返回一个LinkedHashMap
,则无法将其强制转换为HashMap。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.