Pertanyaan Proguard menyebabkan RuntimeException (Unmarshalling unknown type code) di kelas Parcelable


Saya mendapatkan pengecualian ini jika saya meninggalkan aplikasi saya dan membukanya setelah beberapa waktu. Aktivitas utama saya terdiri dari ViewPager dengan tiga fragmen yang berbeda. Saya juga melakukan beberapa hal di kelas Aplikasi yang menurut saya tidak berhubungan dengan masalah.

Ini adalah pengecualian:

RuntimeException (@Parcel: readValue: 2065) {Tidak dapat memulai aktivitas   ComponentInfo {com.emu / com.emu.ActivityMain}:   java.lang.RuntimeException: Parcel android.os.Parcel@419526d0:   Tidak memetakan kode jenis tidak dikenal 2131361816 pada offset 332}

Saya melihat banyak pengecualian ini terjadi pada ponsel pengguna di analytics google. Semua dari mereka adalah sama kecuali nomor setelah readValue dan nomor hex setelah @ yang 2065 dan 419526d0 di atas pengecualian.

Pengecualian tidak menunjukkan baris kode apa pun. Saya mencari tentang ini dan tampaknya itu berkaitan dengan penulisan yang salah ke paket. Meskipun saya tidak memiliki paket di MainActivity saya. Saya tidak tahu apa yang menyebabkan hal ini.

--- EDIT ---------------------------------------------- --------------------------

Saya mereproduksi pengecualian. Ini terjadi ketika App ditinggalkan dengan tombol home, dan terhapus dari memori setelah membuka beberapa aplikasi yang memakan memori lainnya. Ketika memulai lagi pengecualian terjadi. Sampai sekarang saya berpikir bahwa menutup aplikasi dari tugas terakhir atau dari DDMS memiliki efek yang sama tetapi ternyata tidak.

@EricWoodruf membantu saya menemukan bahwa parcel itu ada di suatu tempat di perpustakaan yang diimpor. Saya menemukan paket di PagerSlidingTabStrip yang telah saya unduh dari web. Ini adalah kode yang terkait dengan paket, tetapi saya tidak benar-benar tahu apa yang salah di sini:

public class PagerSlidingTabStrip extends HorizontalScrollView
{
    @Override
    public void onRestoreInstanceState(Parcelable state)
    {
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        currentPosition = savedState.currentPosition;
        requestLayout();
    }

    @Override
    public Parcelable onSaveInstanceState()
    {
        Parcelable superState = super.onSaveInstanceState();
        SavedState savedState = new SavedState(superState);
        savedState.currentPosition = currentPosition;
        return savedState;
    }

    static class SavedState extends BaseSavedState
    {
        int currentPosition;

        public SavedState(Parcelable superState)
        {
            super(superState);
        }

        private SavedState(Parcel in)
        {
            super(in);
            currentPosition = in.readInt();
        }

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

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

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

---- EDIT 2 -------------------------------------------- ---------------------

Setelah saya dapat mereproduksi masalah saya menemukan bahwa ini hanya terjadi di Artifact yang ditandatangani oleh kunci saya dan dicegah! Yang debug tidak memiliki masalah!

Saya menonaktifkan proguard pada artefak dan bekerja seperti pesona tanpa terkecuali. Tapi, apa yang dilakukan proguard yang menghasilkan masalah ini?

Saya mencoba menambahkan ini ke proguard tetapi tidak berfungsi:

-keep class toolfa.android.base.ui.PagerSlidingTabStrip { *; }
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip

ini adalah konfigurasi proguard saya saat ini:

-keep class com.nineoldandroids.** { *; }
-dontwarn com.nineoldandroids.**

-keep class ir.adad.** { *; }
-dontwarn ir.adad.**

-keep class android.support.v4.** { *; }
-dontwarn android.support.v4.**

-keep class toolfa.android.base.ui.PagerSlidingTabStrip { *; }
-dontwarn toolfa.android.base.ui.PagerSlidingTabStrip

-keep class toolfa.android.sega.ActivityEmulator { *; }
-keep class toolfa.android.sega.Zip { *; }

32
2018-01-24 21:22


asal


Jawaban:


Seperti yang kami temukan di komentar, pengecualian adalah hasil dari ProGuard mengaburkan kelas Parcelable. Perbaikannya adalah dengan menyertakan cuplikan ini di file konfigurasi ProGuard:

-keepclassmembers class * implements android.os.Parcelable {
    static ** CREATOR;
}

Saya kira masalah khusus di sini adalah bahwa ProGuard mengaburkan CREATOR anggota dari PagerSlidingTabStrip, tapi sejak itu SavedState adalah subkelas dari View.BaseSavedState, anggota superclass masih tersedia (inilah mengapa tidak melempar a BadParcelableException), tetapi itu menggunakan struktur data yang berbeda dan tidak menulis atribut kustom ke dalam Parcel keluaran.

Ada konfigurasi yang disarankan untuk aplikasi Android yang tersedia di ProGuard Manual, dengan penjelasan rinci tentang entri. Misalnya, ini mencakup bahwa Anda harus menyimpan semua nama kelas yang digunakan dalam manifes atau file XML lainnya.


45
2018-01-27 12:05



Saya rasa saya tahu mengapa ini terjadi. Saya tidak yakin tentang ini jadi saya mungkin salah.

Jadi, dalam kasus saya, saya juga menggunakan viewpager di aplikasi saya untuk menampilkan beberapa data database (menggunakan kursor). Sekarang, jika saya meninggalkan aplikasi di latar belakang dan melanjutkannya setelah jangka waktu yang lama (beberapa jam), Android memutuskan untuk membunuh aplikasi saya. Setelah melanjutkan aplikasi, itu membangun kembali aktivitas saya. Namun, kumpulan data yang mendasari di adaptor saya tidak dipulihkan.

Untuk mengatasi masalah ini, saya meminta kembali data onResume() JIKA getCount() mengembalikan 0.

Di sisi Anda, saya pikir hal yang sama juga terjadi pada aplikasi Anda. Coba letakkan Log in onResume Anda dan lihat apakah ini kasusnya?


-3
2018-01-27 13:13