Вопрос по android, parcelable, android-viewpager – ClassNotFoundException при отмене сортировки: android.support.v4.view.ViewPager $ SavedState

33

Я вижу следующую ошибку в моих отчетах об ошибках Android:

android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.v4.view.ViewPager$SavedState
at android.os.Parcel.readParcelable(Parcel.java:1971)
at android.os.Parcel.readValue(Parcel.java:1859)
at android.os.Parcel.readSparseArrayInternal(Parcel.java:2128)
at android.os.Parcel.readSparseArray(Parcel.java:1581)
at android.os.Parcel.readValue(Parcel.java:1916)
at android.os.Parcel.readMapInternal(Parcel.java:2099)
at android.os.Bundle.unparcel(Bundle.java:223)
at android.os.Bundle.getSparseParcelableArray(Bundle.java:1225)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:806)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:635)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:160)
at android.support.v4.view.ViewPager.populate(ViewPager.java:895)
at android.support.v4.view.ViewPager.populate(ViewPager.java:772)
at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1539)
at android.support.v4.view.ViewPager.computeScroll(ViewPager.java:1422)
at android.view.ViewGroup.drawChild(ViewGroup.java:3028)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)
at android.view.ViewGroup.drawChild(ViewGroup.java:3184)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)
at android.view.ViewGroup.drawChild(ViewGroup.java:3184)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)
at android.view.ViewGroup.drawChild(ViewGroup.java:3184)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788)
at android.view.View.draw(View.java:11017)
at android.widget.FrameLayout.draw(FrameLayout.java:450)
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2175)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2234)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1810)
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2695)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
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:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

Похоже, что это происходит периодически при возобновлении деятельности. У меня нет прямого доступа к классу SavedState в любом коде.

@ user379806, в этом отчете об ошибке есть обходной путь, который фактически решает проблему. Это, безусловно, похоже на ошибку Android. mdelolmo
На code.google.com есть ошибка, связанная с этим:code.google.com/p/android/issues/detail?id=37484 JWGS
Я сталкиваюсь с подобной проблемой, действительно, я осмелюсь сказать, что она идентична. Это начало происходить, когда я сменилFragmentPagerAdapter FragmentStatePagerAdapter. Юо узнал, почему это происходит? П.Д .: Вы должны попытаться включить свой код в свои вопросы о переполнении стека. mdelolmo

Ваш Ответ

5   ответов
27

Моя проблема возникла из-за использования ViewPager с FragmentStatePagerAdapter. Внутри одного из фрагментов из ViewPager был другой ViewPager. Наличие этого пейджера второго вида вызвало эту редкую ошибку. Даже с адаптером или без него.

Решением было просто установить setSaveEnabled (false); на втором ViewPager.

+1 Это именно то, что происходило со мной, ViewPager внутри другого ViewPager, выдающего ошибку, спасибо за ваше простое решение! Невероятный Android до сегодняшнего дня не мог решить эту ошибку.
8

вы можете объявить & quot; исправить & quot; прямо в вашем адаптере

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        final Object fragment = super.instantiateItem(container, position);
        try {
            final Field saveFragmentStateField = Fragment.class.getDeclaredField("mSavedFragmentState");
            saveFragmentStateField.setAccessible(true);
            final Bundle savedFragmentState = (Bundle) saveFragmentStateField.get(fragment);
            if (savedFragmentState != null) {
                savedFragmentState.setClassLoader(Fragment.class.getClassLoader());
            }
        } catch (Exception e) {
            Log.w("CustomFragmentStatePagerAdapter", "Could not get mSavedFragmentState field", e);
        }
        return fragment;
    }
+1, хотя лучше не объединять исключение для сообщения в журнале (так как оно, скорее всего, не вызывается внутреннеe.toString() вернет что-то полезное), но передам отдельно:Log.w("Custom...", "Could not...", e).
@NikitaBosik спасибо, исправлено.
2

FragmentPagerAdapter Вместо того, чтобы использоватьFragmentStatePagerAdapter.Работал для меня как шарм!

Это не работает согласованно во всех ОС Android. Вылетает в некоторых ОС. Вы увидите это, когда начнете тестирование на нескольких устройствах и версиях ОС.
7

public void onSaveInstanceState(Bundle outState){
     //This MUST be done before saving any of your own or your base class's     variables
    final Bundle mapViewSaveState = new Bundle(outState);
    mapView.onSaveInstanceState(mapViewSaveState);
    outState.putBundle("mapViewSaveState", mapViewSaveState);
   //Add any other variables here.
   super.onSaveInstanceState(outState);
}

public void onCreate(Bundle savedInstanceState){
   super.onCreate(savedInstanceState);
   final Bundle mapViewSavedInstanceState = savedInstanceState != null ?      savedInstance.getBundle("mapViewSaveState") : null;
 mapView.onCreate(mapViewSavedInstanceState);
 //....
}

источник:https://code.google.com/p/gmaps-api-issues/issues/detail?id=6237

or another solution is:

map.onCreate (savedInstanceState);

к этому:

map.onCreate (нуль);

Я столкнулся с тем же исключением в представлении карты, и выяснил, что это решение и оно работает для меня сейчас.
Это совершенно не связано
И мой MapView не работал правильно.
14

package android.support.v4.app;

import android.os.Bundle;
import android.view.ViewGroup;

public abstract class FixedFragmentStatePagerAdapter extends FragmentStatePagerAdapter {

  public FixedFragmentStatePagerAdapter(FragmentManager fm) {
    super(fm);
  }

  @Override
  public Object instantiateItem(ViewGroup container, int position) {
    Fragment f = (Fragment)super.instantiateItem(container, position);
    Bundle savedFragmentState = f.mSavedFragmentState;
    if (savedFragmentState != null) {
      savedFragmentState.setClassLoader(f.getClass().getClassLoader());
    }
    return f;
  }

}

отhttp://code.google.com/p/android/issues/detail?id=37484#c1

Можете ли вы добавить резюме к этому ответу? Это сделало бы этот ответ все еще полезным, даже если ссылка когда-либо изменится, или контент будет удален или отредактирован или что-то еще
Что такое mSavedFragmentState? Его нельзя найти в объекте Fragment в моем проекте.
Это защищенное поле. Вы должны поместить свой адаптер в пакет android.support.v4.app для доступа к нему ...

Похожие вопросы