更多课程 选择中心

软件测试培训
达内IT学院

400-996-5531

一个UI BUG引发的血案


起因

最近有同事和用户反馈,说应用首页的 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 哭哭~~

预约申请免费试听课

填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:如果测试和开发有关于bug的争议,该怎么办?
下一篇:如何保证软件工程质量 达内软件测试整理内容

chatGPT在软件测试中七大应用方式

达内软件测试课程全新升级,培养π型测试人才

软件测试流程设计—黑盒测试用例设计方法

学习软件测试需要了解的数据库知识?

Copyright © 2023 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

陕西省

湖南省

贵州省

云南省

广西省

海南省