Parcel.readException 对于 Android 6.0-7.1

Parcel.readException for Android 6.0-7.1

自 12 月 12 日以来,我遇到的错误数量多得离谱。我认为我没有做出任何重大更改,我可能将此归因于 AppCompat 库中的潜在更新。以下为其中一篇日志:

 java.lang.IllegalArgumentException: 
  at android.os.Parcel.readException (Parcel.java:1603)

  at android.os.Parcel.readException (Parcel.java:1552)

  at android.app.ActivityManagerProxy.isTopOfTask (ActivityManagerProxy.java:4986)

  at android.app.Activity.isTopOfTask (Activity.java:5731)

  at android.app.Activity.cancelInputsAndStartExitTransition (Activity.java:4049)

  at android.app.Activity.startActivityForResult (Activity.java:4026)

  at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult (BaseFragmentActivityApi16.java:54)

  at android.support.v4.app.FragmentActivity.startActivityForResult (FragmentActivity.java:67)

  at android.app.Activity.startActivity (Activity.java:4294)

  at android.support.v4.content.ContextCompat.startActivity (ContextCompat.java:143)

关于此问题还有其他一些 Stack Overflow 问题,但它们通常有来自异常的实际消息。最常见的结果是与 AppCompatActivity 调用和 Activity 调用不兼容。

尽管我的所有活动都基于 AppCompat,但我已确保使用 startActivity 进行调用,并使用 ActivityOptions 与其兼容对应项的动画。

有人有什么想法吗?

如果需要源代码,我的 project is completely open source. Anything not in there is in my other library.

我最终无法自己重现错误,但问题似乎主要发生在三星和摩托罗拉设备上。


相关代码片段:

崩溃发生在我的 MainActivity 和 LoginActivity 中,因此这是用户的第一个 activity 转换。

基本主题:

<style name="FrostThemeBase" parent="MaterialDrawerTheme.ActionBar">
    <item name="colorPrimary">@color/facebook_blue</item>
    <item name="colorPrimaryDark">@color/facebook_blue_dark</item>
    <item name="colorAccent">@android:color/white</item>
    <item name="android:windowSoftInputMode">adjustResize</item>
</style>

<style name="FrostTheme" parent="@style/FrostThemeBase">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

其中 MaterialDrawer 扩展了 AppCompat 主题。

我与大多数应用程序的一个区别是我支持动态和透明主题:

fun Activity.setFrostTheme(forceTransparent: Boolean = false) {
    val isTransparent = (Color.alpha(Prefs.bgColor) != 255) || forceTransparent
    if (Prefs.bgColor.isColorDark)
        setTheme(if (isTransparent) R.style.FrostTheme_Transparent else R.style.FrostTheme)
    else
        setTheme(if (isTransparent) R.style.FrostTheme_Light_Transparent else R.style.FrostTheme_Light)
}

对于开始活动,我有以下辅助方法:

inline fun <T : Activity> Context.startActivity(
        clazz: Class<T>,
        clearStack: Boolean = false,
        bundleBuilder: Bundle.() -> Unit = {},
        intentBuilder: Intent.() -> Unit = {}) {
    val intent = Intent(this, clazz)
    if (clearStack) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
    intent.intentBuilder()
    val bundle = Bundle()
    bundle.bundleBuilder()
    startActivity(intent, bundle)
    if (clearStack && this is Activity) finish()
}

总之,对于Login,通过设置clear task和new task flags来清栈,activity就完成了。我现在意识到我确实默认传递了一个空包,所以这可能是一个问题。

还有一些其他差异,例如某些 activity 的自定义 activity 转换,但我认为这不是问题,因为没有它的活动也会崩溃。

这已经有一段时间了,但我认为错误是 bundleBuilder 函数有时为空,导致传递了一个空的 Bundle。解决方案是仅在包非空时才取包,否则使用 null。

这个问题似乎是某些三星设备特有的。