web-dev-qa-db-ja.com

パーセルのアンマーシャリング不明タイプコード

このエラーは、Playストアによって記録されたクラッシュレポートで発生しています。すべてのテストでこれを複製することはできません。他の誰かが同じ問題または解決策を持っていますか?ことは、私たちはこのバグを複製するために何をすべきかさえ知りません。

すべてのParcelableオブジェクトにはCREATOR、writeToParcel()およびcontructorが定義されています。すべてのリストと複合型は初期化され、nullチェックされます。

Java.lang.RuntimeException: Unable to start activity ComponentInfo{au.com.company/au.com.company.DetailsActivity}: Java.lang.RuntimeException: Parcel Android.os.Parcel@42d6e270: Unmarshalling unknown type code 6881381 at offset 11268
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2247)
at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2297)
at Android.app.ActivityThread.access$700(ActivityThread.Java:152)
at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1282)
at Android.os.Handler.dispatchMessage(Handler.Java:99)
at Android.os.Looper.loop(Looper.Java:137)
at Android.app.ActivityThread.main(ActivityThread.Java:5328)
at Java.lang.reflect.Method.invokeNative(Native Method)
at Java.lang.reflect.Method.invoke(Method.Java:511)
at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:1102)
at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:869)
at dalvik.system.NativeStart.main(Native Method)
Caused by: Java.lang.RuntimeException: Parcel Android.os.Parcel@42d6e270: Unmarshalling unknown type code 6881381 at offset 11268
at Android.os.Parcel.readValue(Parcel.Java:2032)
at Android.os.Parcel.readMapInternal(Parcel.Java:2225)
at Android.os.Bundle.unparcel(Bundle.Java:223)
at Android.os.Bundle.getSparseParcelableArray(Bundle.Java:1240)
at Android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:861)
at Android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1104)
at Android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1086)
at Android.support.v4.app.FragmentManagerImpl.dispatchCreate(SourceFile:1872)
at Android.support.v4.app.FragmentActivity.onCreate(SourceFile:215)
at Android.support.v7.app.ActionBarActivity.onCreate(SourceFile:97)
at au.com.company.DetailsActivity.onCreate(SourceFile:40)
at Android.app.Activity.performCreate(Activity.Java:5250)
at Android.app.Instrumentation.callActivityOnCreate(Instrumentation.Java:1097)
at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2211)
... 11 more
20
Manoj Gopal

View.BaseSavedStateの独自の実装を持つカスタムビューで問題が発生していました。そこにあるwriteToParcel()メソッドには、間違った順序でメソッド呼び出しがあることがわかりました。

問題を見つけるのは面倒で、私はAndroid SDKをBundleクラスに至るまでステップデバッグする必要があり、unparcel()が呼び出されます:

synchronized void unparcel() {
    if (mParcelledData == null) {
        return;
    }

    int N = mParcelledData.readInt();
    if (N < 0) {
        return;
    }
    if (mMap == null) {
        mMap = new HashMap<String, Object>(N);
    }
    mParcelledData.readMapInternal(mMap, N, mClassLoader);
    mParcelledData.recycle();
    mParcelledData = null;
}

ログの223行目は、まさにreadMapInternal()呼び出しです。そこでParcelオブジェクトはアイテムを反復処理し、値を1つずつ読み取ります。問題は通常、何かが間違った順序で書かれた場合に発生します。メソッドParcel.readValue(ClassLoader loader)はそれらが書き込まれた順序でそれらを読み取りますが、カスタムビューまたはオブジェクトがある場合、それらが現在読み取っている順序とは異なる順序で書き込まれた場合、何か問題が発生します読み取る次の項目。

そこで、最後に正常に読み取られたアイテムを特定することで問題を発見しました。通常は、その作成者クラス名を確認することで(カスタムビューまたはオブジェクトの場合)識別できます。 ParcelクラスのメソッドreadParcelableCreator()を確認します。

public final <T extends Parcelable> Parcelable.Creator<T> readParcelableCreator(
        ClassLoader loader) {
    String name = readString();
    if (name == null) {
        return null;
    }
...
}

作成者のクラスの名前文字列を検査できます。カスタムの場合は、すぐに識別できます。次に、次の読み取りでアプリがクラッシュした場合、犯人は前の読み取りであったとほぼ確信できます。

それが役に立てば幸い。

22
Ricardo

このエラーも発生しましたが、問題が見つかりました。変数をlongからintに変更しましたが、次の変更を忘れていました。

私はparcel.writeLong(number)を持っていて、それをnumber=parcel.readInt()として読み返しました。正しいのはparcel.writeInt(number)です。

8
David

Parcelableクラスとそれぞれのサブクラスのreadwriteの順序を確認してください。

writeToParcelの順序は、MyParcelable(Parcel in)メソッド内で読み取る順序と同じでなければなりません。

2
HyperionX

Parcelソースの読み取りをオーバーして、戻り値がnullであるかどうかをチェックする代わりにマップに保存するときに、このエラーが発生しました。

String tag = in.readString();
Double value = in.readDouble();
while (tag != null && value != null) {
    this.observations.put(tag, value);
    tag = in.readString();
    value = in.readDouble();
};

パーセルで正しく反復するために使用するintを保存する必要があります。

int numObservations = in.readInt();
String key;
Double value;
for (int i = 0; i < numObservations; i++) {
    key = in.readString();
    value = in.readDouble();
    map.put(tag, value);
}
0
Bruno Peres

小包を読んだときに同じエラーが発生しました。

Parcelableクラスとそれぞれのサブクラスの読み取り/書き込み中にorder and countを確認します。

0
Karen Chang

独自のSavedStateクラスがある場合は、それが保護されていないことと、CREATOR静的属性でないことを確認してください。

次のようなものを使用してください:

# Keeping *SavedState and *SavedState#CREATOR
-keep public final class * extends Android.view.AbsSavedState
-keepclassmembers public final class * extends Android.view.AbsSavedState { *; }
0
William