КлассNotFoundException при unmarshalling: android.support.v4.view.ViewPager $SavedState
В моих отчетах о сбоях в 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 в любом коде.
Ответы
Ответ 1
У меня была такая же ошибка, и вот что я сделал.
Моя проблема возникла при использовании ViewPager с FragmentStatePagerAdapter. Внутри одного из фрагментов из ViewPager был еще один ViewPager. Наличие этого второго пейджера вызывало эту редкую ошибку. Даже с адаптером или без него.
Решением было просто установить setSaveEnabled (false); на втором ViewPager.
Ответ 2
Следующее решение сработало для меня:
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
Ответ 3
Если вы не хотите включать источник в пакет v4, вы можете объявить "исправить" непосредственно в своем адаптере
@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;
}
Ответ 4
В своей деятельности/фрагменте сделайте следующее:
public void onSaveInstanceState(Bundle outState){
//This MUST be done before saving any of your own or your base class 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
или другое решение:
map.onCreate(savedInstanceState);
:
map.onCreate(нуль);
Ответ 5
Ответ может быть запоздалым. Я использовал FragmentPagerAdapter
вместо использования FragmentStatePagerAdapter
. Работал для меня как шарм!