Подтвердить что ты не робот

Proguard вызывает RuntimeException (Unmarshalling неизвестный тип кода) в классе Parcelable

Я получаю это исключение, если оставляю свое приложение и открываю его через некоторое время. Моя основная деятельность состоит из ViewPager с тремя различными фрагментами. Я также делаю некоторые вещи в классе приложений, которые, как я думаю, не связаны с проблемой.

Это исключение:

RuntimeException (@Parcel: readValue: 2065) {Невозможно начать работу ComponentInfo {com.emu/com.emu.ActivityMain}: java.lang.RuntimeException: Parcel [email protected]: Unmarshalling неизвестный код типа 2131361816 при смещении 332}

Я вижу, что это исключение происходит на телефонах пользователей в Google Analytics. Все они одинаковы, кроме числа после readValue и шестнадцатеричного числа после @, которые составляют 2065 и 419526d0 в вышеописанном исключении.

Исключением не указывается какая-либо строка кода. Я искал об этом, и, похоже, это связано с неправильным написанием посылки. Хотя у меня нет никакой посылки в моей MainActivity. Я не знаю, что может это сделать.

--- ИЗМЕНИТЬ ------------------------------------------- -----------------------------

Я воспроизвел исключение. Это происходит, когда приложение выложено с помощью кнопки "домой" и очищается от памяти после открытия другого приложения, использующего всю память. При запуске снова происходит исключение. До сих пор я думал, что закрытие приложения из недавней задачи или из DDMS имеет тот же эффект, но, по-видимому, это не так.

@EricWoodruf помог мне найти этот пакет где-то в импортированной библиотеке. Я нахожу посылку в PagerSlidingTabStrip, которую я загрузил из Интернета. Это код, связанный с посылкой, но я действительно не знаю, что здесь не так:

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

---- ИЗМЕНИТЬ 2 ----------------------------------------- ------------------------

После того, как я смог воспроизвести проблему, я узнал, что это происходит только в Artifact, подписанном моим ключом и предостерегаемым! Проблема с отладкой не вызывает проблем!

Я отключил proguard на артефакте, и он работает как шарм без исключения. Но, что такое proguard, что приводит к этой проблеме?

Я попытался добавить это в proguard, но не работал:

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

это моя текущая конфигурация proguard:

-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 { *; }
4b9b3361

Ответ 1

Как мы выяснили в комментариях, исключение было результатом ProGuard obfuscating Parcelable classes. Исправление состоит в том, чтобы включить этот фрагмент в файл конфигурации ProGuard:

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

Я предполагаю, что конкретная проблема здесь заключалась в том, что ProGuard обфускал член CREATOR PagerSlidingTabStrip, но поскольку SavedState является подклассом View.BaseSavedState, член суперкласса все еще был доступен (поэтому он не выбрал BadParcelableException), но использует другую структуру данных и не писал пользовательские атрибуты в выход Parcel.

Существует рекомендуемая конфигурация для приложений Android, доступных в Руководстве ProGuard, с подробным объяснением записей. Например, он включает в себя, что вы должны хранить все имена классов, используемые в манифесте или других файлах XML.

Ответ 2

Думаю, я знаю, почему это происходит. Я не уверен в этом, поэтому я могу ошибаться.

Итак, в моем случае я также использую viewpager в своем приложении для отображения некоторых данных базы данных (используя курсор). Теперь, если я покину приложение в фоновом режиме и возобновляю его через долгое время (несколько часов), Android решает убить мое приложение. После возобновления приложения он восстанавливает мою активность. Однако базовые данные, установленные в моем адаптере, не восстанавливаются.

Чтобы решить эту проблему, я запрашиваю данные в onResume() IF getCount() возвращает 0.

На твоей стороне я думаю, что то же самое происходит и с твоим приложением. Попробуйте поместить журнал в свой onResume и посмотреть, действительно ли это так?