web-dev-qa-db-ja.com

AndroidのオフセットYYYで不明なタイプコードXXXをアンマーシャリングする方法は?

Unmarshalling例外のため、再開時にアプリがクラッシュします。すべてのSerializableにパラメーターのないコンストラクターがあることを確認し、ObjectStream(ファイルに保存してファイルから読み込む)を使用してすべてのSerializableを確認しました。例外を引き起こすパーセル可能なオフセットの実際のクラスタイプをどのように理解できますか?

Parcel Android.os.Parcel@42209460: Unmarshalling unknown type code
 2131165303 at offset 3748
         at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2080)
         at Android.app.ActivityThread.handleLaunchActivity(ActivityThread.Java:2105)
         at Android.app.ActivityThread.access$600(ActivityThread.Java:136)
         at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1201)
         at Android.os.Handler.dispatchMessage(Handler.Java:99)
         at Android.os.Looper.loop(Looper.Java:137)
         at Android.app.ActivityThread.main(ActivityThread.Java:4876)
         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:804)
         at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:571)
         at com.kdgdev.xtension.core.XtensionMain.main(XtensionMain.Java:91)
         at dalvik.system.NativeStart.main(Native Method)
        Caused by: Java.lang.RuntimeException: Parcel Android.os.Parcel@42209460: Unmarshalling unknown type code 2131165303
 at offset 3748
         at Android.os.Parcel.readValue(Parcel.Java:2032)
         at Android.os.Parcel.readSparseArrayInternal(Parcel.Java:2255)
         at Android.os.Parcel.readSparseArray(Parcel.Java:1687)
         at Android.os.Parcel.readValue(Parcel.Java:2022)
         at Android.os.Parcel.readMapInternal(Parcel.Java:2226)
         at Android.os.Bundle.unparcel(Bundle.Java:223)
         at Android.os.Bundle.getSparseParcelableArray(Bundle.Java:1232)
        at com.Android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.Java:1690)
         at Android.app.Activity.onRestoreInstanceState(Activity.Java:999)
         at com.actionbarsherlock.app.SherlockFragmentActivity.onRestoreInstanceState(Unknown
 Source)
         at name.myname.Android.app.ui.MainActivity.onRestoreInstanceState(Unknown
 Source)
         at Android.app.Activity.performRestoreInstanceState(Activity.Java:971)
         at Android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.Java:1130)
         at Android.app.ActivityThread.performLaunchActivity(ActivityThread.Java:2058)
       ... 12 more

保存されたデータはBundlesとSerializablesで構成され、それらはすべて見栄えが良いです。

私は次のことをするつもりです:

try {
// unmarshalling
} catch (Throwable t) {
// look offset 
}

パーセル可能オフセットの実際のタイプをどのように理解できますか?

26
4ntoine

これは、Proguardの難読化によるものです-Parcelableを処理しました。解決策: ParcelableクラスでRuntimeException(不明な型コードのアンマーシャリング)を引き起こすプロガード

10
4ntoine

区画の書き込みと読み取りにはいくつかのルールがあります。

1-型の不一致に注意してください。 intを記述する場合は、長く読み込もうとしないでください。

2-書き込みと読み取りの順序に注意してください。オブジェクトは、読み取りおよび書き込み時に同じソート順である必要があります。

これらは両方とも「不明な型コードの非整列化」を引き起こす可能性があります。

35
asozcan

リストのタイプが追加される場合、次のようになります。

@Override
    public void writeToParcel(Parcel dest, int flags) {
        super.writeToParcel(dest, flags);
        dest.writeList(this.mList);

次のようなクラスタイプを使用して展開します。

protected MyClass(Parcel in) {
        super(in);
        this.mList = new ArrayList<>();
        in.readList(this.mList, MyRequiredClass.class.getClassLoader());
5
Subhas P

私の場合、サポートライブラリを23.2.1にアップグレードすると修正されます

Proguardに関連する問題ではありません。しかし、proguardとminifyを有効にすると、常に問題が発生します。

問題は、オブジェクトの書き込みと読み取りの順序にあります。ファイルを読み取るのと同じように、シーケンスは同じでなければなりません。

Android parcelableとしてmakeクラスのスタジオプラグインを使用できます https://plugins.jetbrains.com/plugin/7332?pr=

2
Divy Sourabh

すべてのパーセル可能なメソッドを削除し、有効なシーケンスで再度生成するだけです

1
Roshan

追加するだけ:このエラーは、カスタムビューを使用しているときにも発生する可能性があり、onSaveInstanceState()およびonRestoreInstanceState()を介して状態を適切に保存/復元しない。

したがって、このエラーが発生した場合は、カスタムビューも確認してください。

0
Richard R

Kotlinを使用して、オブジェクト「Nota」には、プリミティブプロパティのみを含むカスタムオブジェクト「CentroCusto」があります。

class Nota(var id: Int? = null, var centroCusto: ArrayList<CentroCusto>? = null) : Parcelable {

constructor(source: Parcel) : this(
        source.readValue(Int::class.Java.classLoader) as Int?,
        //Exception in below line -> Unmarshalling unknown type code 
        source.createTypedArrayList(CentroCusto.CREATOR) 
)

override fun describeContents() = 0

override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
    writeValue(id)
    writeTypedList(centroCusto)
}

companion object {
    @JvmField
    val CREATOR: Parcelable.Creator<Nota> = object : Parcelable.Creator<Nota> {
        override fun createFromParcel(source: Parcel): Nota = Nota(source)
        override fun newArray(size: Int): Array<Nota?> = arrayOfNulls(size)
    }
}

CentroCustoクラス:

class CentroCusto(var id: Int? = null, var descricao: String? = null, var aprovacaoDiretoria: Int? = null, var permiteMarcar: Boolean? = null) : Parcelable {

constructor(parcel: Parcel) : this(
        parcel.readValue(Int::class.Java.classLoader) as? Int,
        parcel.readString(),
        parcel.readValue(Int::class.Java.classLoader) as? Int,
        parcel.readValue(Boolean::class.Java.classLoader) as? Boolean) {
}

override fun writeToParcel(parcel: Parcel, flags: Int) {
    parcel.writeValue(id)
    parcel.writeString(descricao)
    parcel.writeValue(aprovacaoDiretoria)
    parcel.writeValue(permiteMarcar)
}

override fun describeContents(): Int {
    return 0
}

companion object CREATOR : Parcelable.Creator<CentroCusto> {
    override fun createFromParcel(parcel: Parcel): CentroCusto {
        return CentroCusto(parcel)
    }

    override fun newArray(size: Int): Array<CentroCusto?> {
        return arrayOfNulls(size)
    }
}

}
0

私の場合、私のクラスは、別のParcelable親から拡張するときにファイルされるCREATORを追加しません。

public class Image implements Parcelable {
        protected Image(Parcel in) {
        }

        public static final Creator<Image> CREATOR = new Creator<Image>() {
            @Override
            public Image createFromParcel(Parcel in) {
                return new Image(in);
            }

            @Override
            public Image[] newArray(int size) {
                return new Image[size];
            }
        };

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
        }
}

public class ImageChild extends Image {
        protected ImageChild(Parcel in) {
            super(in);
        }


        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
        }
}

ImageChildにCREATORフィールドがありません

0
hovo888s

私の場合、それは約1 MBであるパー​​セルに置くことができる最大制限を超えるデータサイズが原因でした。

ソリューション:Parcelableコードを最適化して、できるだけ少ないデータを配置します(たとえば、SerializableオブジェクトをParcelに配置しないでください)

0
Roman Minenok