目录

fragmentManager.commit 的一些潜在问题

目录

前言

最近被 shadow 和 跨进程的 router 搞得头疼,感觉这俩框架跨进程部分写的略微有点混乱。

如果是纯用反射传 className,那就跨进程传字符串,然后再分发咯 = handleMessage 呗,应该写的比较聚合才对。

前几天测试反馈了一个 bug,在 Android 5.0/6.0 的机器上会出现跨进程路由无法跳转的问题,且在 6.0 上,不杀进程回桌面,再打开就又能跳转了。

听听,神奇不?如果是你遇到了这个 bug,你会首先想到什么呢?

当时手上没有手机可以复现,对于跨进程的路由跳转的代码也没有进行了解,所以今天才开始解这个 bug

吐槽1
经常遇到负责一个模块的人,对这个模块一概不知。答复就是:我不清楚,你看主工程怎么写的~~
文档也没,代码一团乱麻,这些人往往还是主力···可悲可叹

吐槽2
大家现在总想搞点黑科技,但是基础知识好差,似乎 mach-o/elf/pe 这些都不太清楚,互联网的面试玄学吧,程序员有啥门槛···

结论

已经很晚了···码不动字了

一路跟着路由框架 debug,加上插件双进程···来回断点···

最终发现了这么一段代码

@Override
public void attach(Activity activity, Intent intent, int requestCode) {
   this.intent = intent;
   this.requestCode = requestCode;
   FragmentManager fragmentManager = ((FragmentActivity)activity).getSupportFragmentManager();
   FragmentTransaction transaction = fragmentManager.beginTransaction();
   transaction.add(this, TAG);
   transaction.commit();
}

这里他们使用一个 fragment 反过来触发 activity 的生命周期,手动调用一下 add commit,在 fragment 的 onCreate 方法中,再调用 activityCompatProxy 的 onCreate 方法,其余生命周期都是一样的分发过程。

为什么这么写,没有细看,可能有一些实现困难的地方

但是这里有一个很明显的问题,commit 并不一定会成功哦!

commit 方法会调用到 enqeueuAction 会 checkStateLoss 哦,如果 mStateSaved = true,会抛异常哦

private void checkStateLoss() {
   if (mStateSaved) {
      throw new IllegalStateException(
               "Can not perform this action after onSaveInstanceState");
   }
   if (mNoTransactionsBecause != null) {
      throw new IllegalStateException(
               "Can not perform this action inside of " + mNoTransactionsBecause);
   }
}

这个 mStateSaved 就是和 onSaveInstanceState 相关联的了

If called, this method will occur after onStop() for applications targeting platforms starting with Build.VERSION_CODES.P. For applications targeting earlier platform versions this method will occur before onStop() and there are no guarantees about whether it will occur before or after onPause().

所以说,这个问题应该在 android 9 以前都可能会发生~~

目前解决办法只能是将 commit 替换为 commitAllowingStateLoss 了

下班下班···