软件测试培训
达内IT学院
400-996-5531
起因
最近有同事和用户反馈,说应用首页的 4 个 tab 在使用了一段时间之后 reselect 重复点击选中时没有触发刷新,并且是小概率事件。本地复现无果后,先进行代码排查。
排查过程
反馈的这个问题有 2 个信息:
· 点击 tab 没有反应(说明执行过程遇到错误)
· 点击 tab 没有崩溃(说明这个错误没有引起闪退)
看了代码后发现,逻辑上并没有条件判断的 return 逻辑,并且在监听 tab 的事件上使用了 RxJava ,那么结论显而易见了,是 RxJava 吃掉了本该引起崩溃的异常。
再往下跟,发现事情可能没有这么简单,这个异常是一个空指针异常,表示某个 ui 控件的成员变量没有初始化。
· ui 控件的成员变量初始化是交给 butterknife 的
· butterknife 的逻辑是在 Fragment 的 onCreateView 方法中执行
说明这个 onCreateView 的生命周期方法没有被执行到,那么为什么没有被执行到呢?联想到用户反馈的一个条件是使用了一段时间,那么这个问题很可能和 savedInstanceState 有关。
一般和 tab 组合使用的 Fragment 会用到 FragmentPagerAdapter ,而我们在对 Fragment 做重用(即利用 savedInstanceState 进行初始化)的时候,不仅仅需要考虑 Fragment 自身的恢复,还要考虑 Fragment 所包含的成员变量的恢复。对于初始化逻辑嵌套好几层的来说,就需要传递好几层的 savedInstanceState ,但代码中明显是漏掉不少的。
提到 savedInstanceState ,就不得不说开发者模式下的不保留活动了。开启不保留活动后,这个问题就变成必现的了。
这让我重新思考到底什么时候需要做恢复。
· 首页的这 4 个 tab 对应的 fragment 是不需要做恢复的
· 在有用户输入的场景(如果没有备份的草稿逻辑,需要做恢复)
· 在数据量不大的关键 ui 上需要做恢复
去掉恢复逻辑后,这个问题解决了,但处理过程中发现了其他的问题。 Fragment 这个东西坑特别多,因为这个东西可以 new 出来,但又有 Activity 类似的生命周期。那么在写代码的时候就要特别注意。
· 尽量不要增加不必要的 public 方法
· 所有的非生命周期 public 方法都要进行 isAdded 的判断和 final 关键字防止 Override
· 特别注意下 setUserVisibleHint 这个方法是不保证在生命周期内的
到这里就结束了么?我也差点以为结束了,结果又发现一个问题,也是不保留活动引起的(或者说使用了很长一段时间,中间只用 home 键切出)。
问题描述:打开若干个页面后,按 home 键切回桌面,再进入后,右滑返回动画异常。
这个问题的原因是切回桌面的时候 MainActivity 被销毁了,再次进入后又重新创建,但其他几个 activity 并没有重新创建(推测是由于 MainActivity 的 singleTask 属性),而右滑返回的动画是依赖于 ActivityStack (手动维护)的,很明显 MainActivity 从 Stack 的栈底被加到栈顶了,造成了动画的异常。
解决方法也比较简单,新增一个叫做 ActivityStackBottom 的接口让 MainActivity 去实现,然后代码如下:
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
if (activity instanceof ActivityStackBottom) {
mActivityStack.add(0, activity);
} else {
mActivityStack.add(activity);
}
}
这样就确保 MainActivity 永远在栈底了。
后话
到这里,目前发现的问题也就解决了,但恐怕其他地方还有不少问题,总结下:
· Android 自己的规则是很重要的东西,对生命周期函数的理解不仅仅在顺序和交互上。
· 一个问题可能会牵涉到另一个问题,解决问题的过程很像《唐人街探案》的案中案,不要轻易地认为事情到这里就结束了。
· 在无法复现的时候多想想代码本身的问题,但也不要过分纠结在代码中,从代码问题追溯到具体场景(比如解决恢复问题并不是完善恢复逻辑,而是先思考需要恢复的场景)。
好了不说了,要去解决另一个棘手的问题了,今天的重构任务要完不成了,但 Never 哭哭~~
填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有
Tedu.cn All Rights Reserved