Flutter启动器Android11端BadParcelableException随机崩溃排查
问题背景
- 开发的Flutter应用定位为系统桌面启动器,存在无规律随机崩溃问题,无稳定复现路径
- 目前观测到崩溃仅发生在Android 11设备上,先后切换多个Flutter正式版本(含最新Flutter 3版本)构建应用,崩溃率无明显下降
- 已在Google Issue Tracker、技术人员公开社交平台检索到同类问题反馈,但无法定位问题根源属于Android系统缺陷、Flutter框架问题、应用配置错误还是其他原因,需要可行的排查与修复方向
崩溃对应堆栈信息如下:
java.lang.RuntimeException: at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3502) at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3654) at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2116) at android.os.Handler.dispatchMessage (Handler.java:106) at android.os.Looper.loop (Looper.java:223) at android.app.ActivityThread.main (ActivityThread.java:7720) at java.lang.reflect.Method.invoke (Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:612) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:997) Caused by: android.os.BadParcelableException: at android.os.Parcel.readParcelableCreator (Parcel.java:3367) at android.os.Parcel.readParcelable (Parcel.java:3272) at android.os.Parcel.readValue (Parcel.java:3174) at android.os.Parcel.readArrayMapInternal (Parcel.java:3567) at android.os.BaseBundle.initializeFromParcelLocked (BaseBundle.java:292) at android.os.BaseBundle.unparcel (BaseBundle.java:236) at android.os.BaseBundle.getBoolean (BaseBundle.java:935) at android.app.Activity.restoreHasCurrentPermissionRequest (Activity.java:8297) at android.app.Activity.performCreate (Activity.java:7996) at android.app.Activity.performCreate (Activity.java:7984) at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3475) at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3654) at android.app.servertransaction.LaunchActivityItem.execute (LaunchActivityItem.java:85) at android.app.servertransaction.TransactionExecutor.executeCallbacks (TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute (TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage (ActivityThread.java:2116) at android.os.Handler.dispatchMessage (Handler.java:106) at android.os.Looper.loop (Looper.java:223) at android.app.ActivityThread.main (ActivityThread.java:7720) at java.lang.reflect.Method.invoke (Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:612) at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:997)
根因判定
从堆栈可以直接定位,崩溃触发点是Android 11系统在Activity创建阶段,执行restoreHasCurrentPermissionRequest读取恢复状态Bundle时抛出BadParcelableException,本质是Android 11的系统级Bug:系统恢复Activity状态时,没有给Bundle设置正确的类加载器,解析Parcelable对象时类加载失败。
桌面启动器作为系统常驻应用,会被系统频繁调度重建、触发权限请求流程,触发该Bug的概率远高于普通应用。因为问题出在Android系统框架层,和Flutter版本无关联,所以切换Flutter版本构建不会改变崩溃率。
可落地修复方案
以下修复方案仅针对Android 11(API 30)生效,不要在更高版本Android系统上应用,避免影响系统正常的状态恢复逻辑:
- 方案1:禁用主Activity的系统自动状态保存
重写MainActivity的onSaveInstanceState方法,不调用父类实现,阻止系统写入可能异常的序列化状态。如果应用自身有需要持久化的页面状态,改用SharedPreferences、本地文件等方式独立存储,不要依赖系统的savedInstanceState机制。
参考实现代码:override fun onSaveInstanceState(outState: Bundle) { // 不执行super.onSaveInstanceState(outState),规避Android 11 Parcelable解析异常 } - 方案2:给恢复状态Bundle手动设置正确的类加载器
如果需要保留系统状态恢复能力,重写MainActivity的onCreate方法,在调用父类onCreate之前,给传入的savedInstanceState Bundle设置当前应用的类加载器,解决类加载不匹配问题。
参考实现代码:override fun onCreate(savedInstanceState: Bundle?) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) { savedInstanceState?.classLoader = classLoader } super.onCreate(savedInstanceState) } - 方案3:兜底拦截Activity创建阶段的解析异常
给主线程Handler添加自定义回调,拦截Bundle解析相关的BadParcelableException,触发异常时直接清空savedInstanceState数据,走无状态的Activity启动流程,避免闪退。
验证步骤
- 测试阶段打开Android 11设备开发者选项中的「不保留活动」开关,反复执行切后台、按Home返回桌面、弹出权限申请后强杀应用重启等操作,验证崩溃是否消失
- 灰度发布修复包后,对比Google Play控制台Android 11设备的崩溃率数据,确认修复效果
- 回归验证Android 12及以上版本设备的功能,确保修复逻辑没有影响高版本系统的正常运行
内容的提问来源于stack exchange,提问作者Michael Vogt
相关产品推荐
相关产品推荐

