How to fix Unmarshalling unknown type code XXX at offset YYY in Android?
Asked Answered
R

12

47

I'm having app crash on resume because of Unmarshalling exception. I've checked all the Serializables have constructor with no parameters and even checked all the serializables using ObjectStream (save to file and load from file). How can i understand actual class type for parcelable offset that cause exception:

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

Saved data consists of Bundles and Serializables and all of them look good.

I'm going to do the next:

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

How can i understand what type is actually for Parcelable offset?

Rabe answered 18/2, 2014 at 5:17 Comment(1)
It happened to me because I didn't read an int value from my Parcel (but was writing to it). It messed up everything and the app got crashed.Maddy
R
14

It's because of Proguard obfuscation - it processed Parcelable. solution: Proguard causing RuntimeException (Unmarshalling unknown type code) in Parcelable class

Rabe answered 31/3, 2014 at 12:1 Comment(5)
Same problem but it happens while debuging so this is not solution for me - another idea?Evitaevitable
@Evitaevitable have you found a solution? Did it happen only on 6.x or other versions too?Viridis
@Viridis no, I cant remember what problem was it - If I come across this problem again I can answer you but I think I used another approach to avoid unmarshalling problemsEvitaevitable
For what it's worth, it might be your implementation as well. I had this issue recently with a custom ViewGroup I wrote. I did not make the CREATOR static, so it was throwing this error on rotation when the Activity was destroyed. It was easy to replicate by turning on "Don't keep activities" in the Developer Options.Fossette
@Fossette it might be due to some reading from/writing to Parcel. In my case, I was writing to Parcel but not reading from it. It resulted in a mess when instance state was restoring.Maddy
T
63

There's some rules for write and read parcelables.

1- Be careful about type mismatch. If you write int, don't try to read long etc.

2- Be careful about order of writes and reads. Objects must be at the same sort order when reading and writing.

Both of these can cause "Unmarshalling unknown type code".

Teodorateodorico answered 4/5, 2016 at 13:52 Comment(3)
This was my solution: Be careful about order of writes and reads. Objects must be at the same sort order when reading and writing.Dunseath
3 - Be careful about order of writes and reads in field of Parcelable type if have one . The field of Parcelable type must be at the same sort order when reading and writing.Grinnell
Because the exception may be occurred where not exactly the stack trace show. For example: the stack trace show field A cause the exception, but in fact it is field B of of parcelable type cause the exception.Grinnell
R
14

It's because of Proguard obfuscation - it processed Parcelable. solution: Proguard causing RuntimeException (Unmarshalling unknown type code) in Parcelable class

Rabe answered 31/3, 2014 at 12:1 Comment(5)
Same problem but it happens while debuging so this is not solution for me - another idea?Evitaevitable
@Evitaevitable have you found a solution? Did it happen only on 6.x or other versions too?Viridis
@Viridis no, I cant remember what problem was it - If I come across this problem again I can answer you but I think I used another approach to avoid unmarshalling problemsEvitaevitable
For what it's worth, it might be your implementation as well. I had this issue recently with a custom ViewGroup I wrote. I did not make the CREATOR static, so it was throwing this error on rotation when the Activity was destroyed. It was easy to replicate by turning on "Don't keep activities" in the Developer Options.Fossette
@Fossette it might be due to some reading from/writing to Parcel. In my case, I was writing to Parcel but not reading from it. It resulted in a mess when instance state was restoring.Maddy
P
11

If a type of List is added, it should be:

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

and unparcel it using the class type like this:

protected MyClass(Parcel in) {
        super(in);
        this.mList = new ArrayList<>();
        in.readList(this.mList, MyRequiredClass.class.getClassLoader());
Psychologism answered 7/4, 2017 at 11:54 Comment(1)
If your getting this error after adding List into your class which implements Parcelable then this was what fixed it for me.Staphylo
D
4

In my case it is fixed after upgrading support library to 23.2.1

Dermatoglyphics answered 7/4, 2016 at 14:36 Comment(1)
I wonder what was the problem, because I don't see any related issue at developer.android.com/topic/libraries/support-library/…Chilt
A
4

It's not Proguard related issue.. But when proguard and minify enable it's issue occurrence is always.

Problem is in sequence of writing and reading of object...sequence should be same, as it is like reading file.

You can use android studio plug in for make class as parcelable https://plugins.jetbrains.com/plugin/7332?pr=

Ananna answered 22/4, 2016 at 8:11 Comment(1)
I wasted couple of hours to fix this issue. I faced same issue you suggestion saved me read and write order should be sameGehring
G
4

In my case my class don't added CREATOR filed when extending from another Parcelable parent.

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

In ImageChild missing CREATOR field

Grackle answered 7/2, 2018 at 8:35 Comment(0)
A
4

Just remove all parcelable methods and generate them again with valid sequence

Armorer answered 28/11, 2018 at 10:51 Comment(0)
B
2

In my case it was caused by data size exceeding max limit of that can be put to Parcel which is about 1 MB.

Solution: optimize your Parcelable code to put as less data as possible (e.g. do not put Serializable objects to Parcel)

Bicycle answered 21/9, 2016 at 11:48 Comment(0)
C
2

Using Kotlin, the object 'Nota' has a Custom object 'CentroCusto' that contains only primitive properties.

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

The CentroCusto class:

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

}
Cullis answered 16/2, 2018 at 17:39 Comment(0)
S
1

Just to add: this error can also happen, when using custom views and don't properly save/restore their states via onSaveInstanceState() and onRestoreInstanceState().

So if this error occurs, also check your custom views.

Selfdelusion answered 27/4, 2019 at 11:52 Comment(1)
Fo me, it was about wrong declaration of CREATOR field in one of the custom views.Gates
T
1

Parent Model have parcelable and Child Model have parcelable then used below code works fine and not getting unmarshalling error

Parent Model

data class ParentModel(
    @SerializedName("post_id") val post_id: String? = "",
    @SerializedName("images") val images: ArrayList<ChildModel>? = null
) : Parcelable {
   constructor(parcel: Parcel) : this(
        parcel.readString(),
        parcel.createTypedArrayList(ChildModel.CREATOR)!!
   )

   override fun writeToParcel(parcel: Parcel, flags: Int) {
       parcel.writeString(post_id)
       parcel.writeTypedList(images)
   }

   override fun describeContents(): Int {
       return 0
   }

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

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

Child Model

data class ChildModel(
    @SerializedName("image_id") val image_id: String? = "",
    @SerializedName("image_url") val image_url: String? = ""
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString(),
        parcel.readString()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(image_id)
        parcel.writeString(image_url)
    }

    override fun describeContents(): Int {
        return 0
    }

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

        override fun newArray(size: Int): Array<ChildModel?> {
            return arrayOfNulls(size)
        }
    }
}
Toxophilite answered 10/12, 2020 at 19:4 Comment(0)
T
1

In my case it was due to a library called SimpleSearchView. The CREATOR field in the SavedState of the library lacked @JvmField annotation.

Touchstone answered 31/3, 2023 at 11:51 Comment(1)
That was my case! Thank you! And BTW This has been fixed by the new update github.com/Ferfalk/SimpleSearchView/releases/tag/0.2.1Critter

© 2022 - 2024 — McMap. All rights reserved.