19

私の Android アプリケーションでは、いくつかのアンマーシャリング エラーが発生しますが、Parcelables. 私のコードの何が問題なのか教えていただけますか?

エラー 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)

の1012 行目はのへのMyActivity呼び出しです。super.onCreate(savedInstanceState);ActivityonCreate()

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);
}

myObjectMyObject次のメソッドを持つクラスです。

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());
}

エラー 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)

同じファイルとクラス。

エラー 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)

今回、原因となる行 (1111) は次の行です。

myObject = (MyObject) savedInstanceState.getParcelable("myObject");
4

3 に答える 3

54

Androidには、フレームワーククラスローダー(Androidクラスのロード方法を知っている)とAPKクラスローダー(コードのロード方法を知っている)の2つの異なるクラスローダーがあります。APKクラスローダーには、親としてフレームワーククラスローダーが設定されています。つまり、Androidクラスをロードすることもできます。

エラー#2は、フレームワーククラスローダーを使用しているバンドルが原因である可能性が高いため、クラスを認識していません。これは、Androidがバンドルを永続化し、後で復元する必要がある場合に発生する可能性があると思います(たとえば、バックグラウンドでメモリが不足している場合)。これを修正するには、バンドルにAPKクラスローダーを設定します。

savedInstanceState.setClassLoader(getClass()。getClassLoader());

エラー#1と#3はもっと不思議ですが、おそらくnull値を書き込んでいますwriteToParcel()か?Androidはそれをあまり好きではありません。

于 2012-12-30T19:12:12.710 に答える
3

バンドルから読み取る前に、ClassLoader を設定します。

bundle.setClassLoader(getClass().getClassLoader());

これで時間を節約できました!

于 2016-11-19T17:18:00.043 に答える
2

見てみると、createFromParcelandは次のnewArrayようにオーバーライドする必要があります。

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];
    }
};

編集:

上記が機能するためには、空のコンストラクターが必要であることに言及するのを忘れていました!

public MyObject(){}
于 2012-12-21T21:54:48.393 に答える