android.view.AbsSavedState$1 无法强制转换为 android.widget.CompoundButton$SavedState

17

我在Crashlytics上看到了很多次以下错误:

Caused by java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.widget.CompoundButton$SavedState
       at android.widget.CompoundButton.onRestoreInstanceState(CompoundButton.java)
       at android.view.View.dispatchRestoreInstanceState(View.java)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java)
       at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java)
       at android.view.View.restoreHierarchyState(View.java)
       at android.support.v4.app.Fragment.restoreViewState(Fragment.java:494)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1486)
       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
       at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
       at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
       at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:2466)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1483)
       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1784)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1852)
       at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3269)
       at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3229)
       at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:201)
       at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:620)
       at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
       at android.app.Instrumentation.callActivityOnStart(Instrumentation.java)
       at android.app.Activity.performStart(Activity.java)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java)
       at android.app.ActivityThread.access$900(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java)
       at android.os.Handler.dispatchMessage(Handler.java)
       at android.os.Looper.loop(Looper.java)
       at android.app.ActivityThread.main(ActivityThread.java)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)

然而,这个堆栈跟踪并没有涉及到我的代码库,因为异常是在平台级别抛出的。

从我所阅读的内容来看,这可能与重复的ID有关,但是我在我的代码中找不到任何重复的ID,请问有什么办法可以调试这个问题吗?

我还尝试在开发者选项中启用“不保留活动”以强制进行实例恢复,但我无法手动重现崩溃。


1
有一个活动,在 onStart 中恢复了一个片段。您是否有包含 RadioButtonCheckboxSwitchToggleButton 的片段?如果有,请尝试在那里设置断点,并在 Watches 窗口 中检查是否将它们转换错误。 - deadfish
你的项目中是否有任何自定义的 View 子类,它们派生自 CompoundButton(或其子类)? - Ben P.
如果可能的话,请尝试在出现问题的设备上进行操作,并在您的应用程序处于前台时在不同的时刻切换应用程序(特别是在使用CompoundButton的片段视图上),然后切换回您的应用程序。看起来问题发生在从保存的状态恢复视图时,但复制可能是与设备有关的。 - LLL
可能是由于横屏和竖屏模式之间的布局结构变化导致了这种情况发生。 - jpmcosta
4个回答

9

没有查看代码或实际的活动/片段类,很难准确地确定问题,但有以下原因可能有助于您进行更多调试:

  1. 您可能具有重复的ID名称或相应视图,这会在转换时创建内存泄漏。

  2. 可能导入了错误的CompoundButton,可能正在使用自定义视图或版本受到影响。


8

事实证明我正在使用新的芯片组件(扩展CompoundButton),并且有一个组中有一个没有id的芯片。

这些原因导致在旧手机上(Android 6)应用程序崩溃,因为多个芯片被分配相同的id,我只能猜测。

我删除了那个不必要的芯片,现在它不再崩溃。


3
这可能是由于具有相同resId的视图,与包含布局的名称相同(主要原因)引起的。
它也可能是由于具有重复resId的视图引起的,但这不太可能是原因。
审查所有片段的XML建议(难以确定哪一个导致了问题)。
但是,编辑 > 查找 > 在路径中查找 ...使搜索出现次数变得容易;
先搜索一个布局名称,然后搜索视图的resId

1
如果自定义视图继承自 Layout 类,则可能会发生此情况。当您使用这样的视图时,它的 ID 命名空间将合并到放置它的布局的命名空间中,创建在编译时不可见的冲突。 - Dmitry K

0
在我的情况下,我从所有包含的布局中移除了滚动视图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接