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 了
下班下班···