我尝试在实现ClassNotFoundException
的自定义类中解组List<List<LatLng>
时得到Parcelable
。我该如何摆脱这种例外?
这是我的班级:
public class Country implements Parcelable {
public static final Parcelable.Creator<Country> CREATOR = new Creator<Country>() {
@Override
public Country[] newArray(int size) {
return new Country[size];
}
@SuppressWarnings("unchecked")
@Override
public Country createFromParcel(Parcel source) {
Country country = new Country();
country.name = source.readString();
country.borders = source.readArrayList(Country.class
.getClassLoader());
return country;
}
};
public String name;
public List<List<LatLng>> borders;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeList(borders);
}
}
这是我的logcat:
03-08 22:09:43.749: E/AndroidRuntime(16991): FATAL EXCEPTION: main
03-08 22:09:43.749: E/AndroidRuntime(16991): java.lang.RuntimeException: Unable to start activity ComponentInfo{codeguru.worldtour/codeguru.worldtour.MainActivity}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: codeguru.worldtour.Country
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1654)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1670)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2844)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.ActivityThread.access$1600(ActivityThread.java:117)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Handler.dispatchMessage(Handler.java:99)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Looper.loop(Looper.java:130)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.ActivityThread.main(ActivityThread.java:3695)
03-08 22:09:43.749: E/AndroidRuntime(16991): at java.lang.reflect.Method.invokeNative(Native Method)
03-08 22:09:43.749: E/AndroidRuntime(16991): at java.lang.reflect.Method.invoke(Method.java:507)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
03-08 22:09:43.749: E/AndroidRuntime(16991): at dalvik.system.NativeStart.main(Native Method)
03-08 22:09:43.749: E/AndroidRuntime(16991): Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling: codeguru.worldtour.Country
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Parcel.readParcelable(Parcel.java:1958)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Parcel.readValue(Parcel.java:1846)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Parcel.readListInternal(Parcel.java:2092)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Parcel.readArrayList(Parcel.java:1536)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Parcel.readValue(Parcel.java:1867)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Parcel.readMapInternal(Parcel.java:2083)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Bundle.unparcel(Bundle.java:208)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Bundle.getBundle(Bundle.java:1078)
03-08 22:09:43.749: E/AndroidRuntime(16991): at ekg.a(SourceFile:74)
03-08 22:09:43.749: E/AndroidRuntime(16991): at maps.e.al.a(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at maps.e.bj.a(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at eir.onTransact(SourceFile:66)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.os.Binder.transact(Binder.java:279)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.maps.internal.IMapViewDelegate$a$a.onCreate(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.maps.MapView$a.onCreate(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.dynamic.a$3.b(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.dynamic.a$1.a(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.maps.MapView$b.eb(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.maps.MapView$b.a(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.dynamic.a.a(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.dynamic.a.onCreate(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at com.google.android.gms.maps.MapView.onCreate(Unknown Source)
03-08 22:09:43.749: E/AndroidRuntime(16991): at codeguru.worldtour.MainActivity.onCreate(MainActivity.java:63)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
03-08 22:09:43.749: E/AndroidRuntime(16991): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1618)
03-08 22:09:43.749: E/AndroidRuntime(16991): ... 12 more
编组:
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putParcelableArrayList(COUNTRIES_KEY, countries);
savedInstanceState.putInt(COUNTRIES_INDEX_KEY, countryIndex);
}
解组(onCreate()
):
if (savedInstanceState != null) {
countryIndex = savedInstanceState.getInt(COUNTRIES_INDEX_KEY, -1);
countries = savedInstanceState
.getParcelableArrayList(COUNTRIES_KEY);
}
答案 0 :(得分:1)
编辑:
确保LatLng
实施Parcelable
。否则,当必须编组/解组Country
时,活动将不知道如何编组和取消编组(这就是为什么您可能会收到错误:The inferred type List<LatLng> is not a valid substitute for the bounded parameter <T extends Parcelable>
。
这应该有用 - 创建一个扩展ArrayList<LatLng>
的类。我们的想法是使用CREATOR
ParcelableArrayList
(下面的课程)来创建您的列表。它只有在您将列表实例化为ArrayList
时才会起作用(如您提到的另一个答案)。
public class ParcelableArrayList extends ArrayList<LatLng> implements
Parcelable {
public ParcelableArrayList(){
super();
}
protected ParcelableArrayList(Parcel in) {
in.readList(this, LatLng.class.getClassLoader());
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(this);
}
public static final Parcelable.Creator<ParcelableArrayList> CREATOR = new Parcelable.Creator<ParcelableArrayList>() {
public ParcelableArrayList createFromParcel(Parcel in) {
return new ParcelableArrayList(in);
}
public ParcelableArrayList[] newArray(int size) {
return new ParcelableArrayList[size];
}
};
}
现在,在Country
课程中:
public class Country implements Parcelable {
public static final Parcelable.Creator<Country> CREATOR = new Creator<Country>() {
@Override
public Country[] newArray(int size) {
return new Country[size];
}
@SuppressWarnings("unchecked")
@Override
public Country createFromParcel(Parcel source) {
return new Country(in);
}
};
public String name;
public List<ParcelableArrayList> borders;
public Country(Parcel source) {
country.name = source.readString();
country.borders = new ArrayList<ParcelableArrayList()>();
country.borders = source.readTypedList(ParcelableArrayList.CREATOR);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeList(borders);
}
}
编辑2:
好的,请尝试使用Parcel#readTypedList()
,而不是使用Parcel#readList()
阅读。所以替换:
country.borders = new ArrayList<ParcelableArrayList()>();
country.borders = source.readTypedList(ParcelableArrayList.CREATOR);
与
country.borders = new ArrayList<ParcelableArrayList()>();
country.borders = source.readList(country.borders, ParcelableArrayList.class.getClassLoader());
我在自己的应用程序中对此进行了测试,并且没有编译时间或运行时错误(据我所见)。
答案 1 :(得分:0)
点击此处的主题以及对答案的所有评论:https://stackoverflow.com/a/4915219/693752
可能有趣的是:
parcel.writeTypedList(List)
编写边框列表parcel.createTypedArrayList
从包裹中读取它。看起来readArrayList
很难处理。答案 2 :(得分:0)
添加一个构造函数,该构造函数将parcel作为参数并将一个Creator添加到您的类中。
public Country(Parcel source) {
country.name = source.readString();
country.borders = source.readArrayList(Country.class
.getClassLoader());
}
@SuppressWarnings("rawtypes")
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Country createFromParcel(Parcel in) {
return new Country(in);
}
public Country[] newArray(int size) {
return new Country[size];
}
};
答案 3 :(得分:0)
我通过将List<List<LatLng>>
分成List<CustomClass>
来解决这个问题
其中CustomClass extends ArrayList<LatLng>>
这是我的CustomClass代码
import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;
public class Lister extends ArrayList<AlertEvaluation> implements Parcelable {
protected Lister(Parcel in) {
this.addAll(in.readArrayList(AlertEvaluation.class.getClassLoader()));
}
public static final Creator<Lister> CREATOR = new Creator<Lister>() {
@Override
public Lister createFromParcel(Parcel in) {
return new Lister(in);
}
@Override
public Lister[] newArray(int size) {
return new Lister[size];
}
};
@Override public int describeContents() {
return 0;
}
@Override public void writeToParcel(Parcel parcel, int flags) {
parcel.writeList(this);
}
}