【问题标题】:ClassNotFoundException when unmarshalling: android.support.v4.view.ViewPager$SavedState解组时出现 ClassNotFoundException:android.support.v4.view.ViewPager$SavedState
【发布时间】:2012-07-08 07:34:14
【问题描述】:

我在 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 类。

【问题讨论】:

  • 我遇到了类似的问题,确实,我敢说它是相同的。当我将FragmentPagerAdapter 切换到`FragmentStatePagerAdapter.你有没有发现为什么会这样? P.D:您应该尝试在堆栈溢出问题中包含您的一些代码。
  • code.google.com 上有一个与此相关的错误:code.google.com/p/android/issues/detail?id=37484
  • @user379806,在该错误报告中,有一种解决方法实际上可以解决该问题。这似乎是一个 Android 错误。

标签: android android-viewpager parcelable


【解决方案1】:

我遇到了同样的错误,这就是我所做的。

我的问题来自于将 ViewPager 与 FragmentStatePagerAdapter 一起使用。 ViewPager 中的一个片段内部有另一个 ViewPager。拥有第二个视图寻呼机导致了这个罕见的错误。即使有或没有适配器。

解决方案是简单地设置 setSaveEnabled(false);在第二个 ViewPager 上。

【讨论】:

  • +1 这正是发生在我身上的另一个 ViewPager 中的 ViewPager 给出的错误,感谢您的简单解决方案!令人难以置信的 Android 直到今天都没有解决这个错误。
【解决方案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

【讨论】:

  • 您能否在此答案中添加摘要?即使链接发生变化或内容被删除或编辑或其他任何情况,这将使这个答案仍然有用。
  • 什么是 mSavedFragmentState?在我的项目的 Fragment 对象中找不到它。
  • 这是一个受保护的字段。您必须将适配器放入包 android.support.v4.app 才能访问它...
【解决方案3】:

在您的 Activity/Fragment 中,执行以下操作:

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

或其他解决方案是:

map.onCreate(savedInstanceState);

到这里:

map.onCreate(null);

【讨论】:

  • 这完全不相关
  • 我在地图视图中遇到了同样的异常,现在找出这个解决方案及其对我有用。
  • mapView 将在 OnCreate() 中为空...这是如何工作的?
  • 这是在 xml 文件中声明 MapView 并使用 findViewById 获取。
【解决方案4】:

如果您不想在 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;
    }

【讨论】:

  • +1,尽管您最好不要将异常连接到日志消息(因为内部调用 e.toString() 不太可能返回有用的信息),但要单独传递:Log.w("Custom...", "Could not...", e)
【解决方案5】:

回答可能会迟到。我使用FragmentPagerAdapter 而不是FragmentStatePagerAdapter。像魅力一样为我工作!

【讨论】:

  • 这并非在所有 Android 操作系统中都能始终如一地工作。它在某些操作系统中崩溃。当您开始在多个设备和操作系统版本中进行测试时,您会看到这一点。
猜你喜欢
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
相关资源
最近更新 更多