example - parcelable android studio
Errores irrelevantes en la aplicaciĆ³n de Android con clases personalizables parcelable (3)
Para mi aplicación de Android, recibo varios errores irrelevantes, aunque creo que he hecho todo lo necesario para guardar y cargar objetos Parcelable
través de Parcelable
s. ¿Puedes decirme qué está mal con mi código?
Error 1:
java.lang.RuntimeException: Unable to start activity ComponentInfo
Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@41279860: Unmarshalling unknown type code 6619241 at offset 1372
at android.os.Parcel.readValue(Parcel.java:1922)
at android.os.Parcel.readMapInternal(Parcel.java:2094)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getParcelable(Bundle.java:1158)
at android.app.Activity.onCreate(Activity.java:860)
at my.app.package.PlayComputer.onCreate(PlayComputer.java:1012)
at android.app.Activity.performCreate(Activity.java:4465)
La línea 1012 en MyActivity
es la llamada a super.onCreate(savedInstanceState);
en la Activity
de onCreate()
.
protected void onSaveInstanceState(Bundle savedInstanceState) {
if (myObject == null) {
savedInstanceState.putParcelable("myObject", null);
}
else {
savedInstanceState.putParcelable("myObject", myObject);
}
savedInstanceState.putInt(...);
savedInstanceState.putString(...);
savedInstanceState.putBoolean(...);
super.onSaveInstanceState(savedInstanceState);
}
myObject
es de la clase MyObject
que tiene los siguientes métodos:
public void writeToParcel(Parcel out, int flags) {
out.writeIntArray(...);
out.writeInt(...);
out.writeStringArray(...);
out.writeString(...);
out.writeParcelableArray(..., flags);
}
public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
public MyObject createFromParcel(Parcel in) {
try {
if (in == null) {
return null;
}
else {
return new MyObject(in);
}
}
catch (Exception e) {
return null;
}
}
public MyObject[] newArray(int size) {
return new MyObject[size];
}
};
private MyObject(Parcel in) {
in.readIntArray(...);
... = in.readInt();
in.readStringArray(...);
... = in.readString();
... = (OtherObject[]) in.readParcelableArray(OtherObject.class.getClassLoader());
}
Error 2:
java.lang.RuntimeException: Unable to start activity ComponentInfo
Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling:
at android.os.Parcel.readParcelable(Parcel.java:1971)
at android.os.Parcel.readValue(Parcel.java:1859)
at android.os.Parcel.readMapInternal(Parcel.java:2099)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getParcelable(Bundle.java:1158)
at android.app.Activity.onCreate(Activity.java:905)
at my.app.package.PlayComputer.onCreate(SourceFile:1012)
Mismos archivos y clases.
Error 3:
java.lang.RuntimeException: Unable to start activity ComponentInfo
Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@4051aff8: Unmarshalling unknown type code 7340149 at offset 1276
at android.os.Parcel.readValue(Parcel.java:1913)
at android.os.Parcel.readMapInternal(Parcel.java:2083)
at android.os.Bundle.unparcel(Bundle.java:208)
at android.os.Bundle.getParcelable(Bundle.java:1100)
at my.app.package.PlayComputer.onCreate(SourceFile:1111)
Esta vez, la línea causante (1111) es la siguiente:
myObject = (MyObject) savedInstanceState.getParcelable("myObject");
Android tiene dos cargadores de clases diferentes: el cargador de clases de marco (que sabe cómo cargar clases de Android) y el cargador de clases APK (que sabe cómo cargar su código). El cargador de clases APK tiene el cargador de clases marco como principal, lo que significa que también puede cargar clases de Android.
El error # 2 es probablemente causado por el paquete que usa el cargador de clases del framework, por lo que no conoce sus clases. Creo que esto puede suceder cuando Android necesita conservar su paquete y luego restaurarlo (por ejemplo, cuando se queda sin memoria en segundo plano). Puede solucionar esto configurando el cargador de clases APK en el paquete:
savedInstanceState.setClassLoader (getClass (). getClassLoader ());
Los errores # 1 y # 3 son más misteriosos, ¿quizás esté escribiendo valores nulos en writeToParcel()
? A Android no le gusta mucho eso, me temo.
Antes de leer el paquete, establezca ClassLoader:
bundle.setClassLoader(getClass().getClassLoader());
Esto ahorró mi tiempo!
Por su aspecto, createFromParcel
y newArray
deben anular de esta manera:
public static final Parcelable.Creator<MyObject> CREATOR = new Parcelable.Creator<MyObject>() {
@Override
public MyObject createFromParcel(Parcel in) {
MyObject myObj = new MyObject();
myObj.intArray = in.readIntArray(...);
myObj.intValue = in.readInt(...);
// ....
// IN THE SAME ORDER THAT IS WRITTEN OUT AS PER writeToParcel!
//
return myObj;
}
@Override
public MyObject[] newArray(int size) {
return new MyObject[size];
}
};
Editar:
Olvidé mencionar que para que lo anterior funcione, ¡debería haber un constructor vacío!
public MyObject(){}