在做新增图片tab需求的时候,需要按照规范,将tab对应的配置(即tabConfig)加上,然后创建该tab下的Fragment,及其相应的功能Component。
object SearchResultTabs {
val tabBuildConfigMap by lazy {
mutableMapOf<SearchResultTabPageType, AbsSearchResultTabBuildConfig>().apply {
// 图片Tab
if (AliothAbTestCenter.getSearchResultImageTabPos() >= 0 && DeviceInfoContainer.isNormalDevice()) {
...
}
}
}
在这段代码中,因为需要根据实验来确定是否添加新的图片tab,所以我也是加上了if..else的实验逻辑判断。
很快啊,fragment、组件啥的都写完了,打个包给QA测试。到要上线的最后一天,QA发现:从对照组账号切到实验组账号,不冷启的状态下,进入搜索页会发生Crash。具体crash如下:
通过堆栈我们可以看到,是没有找到IMAGES的配置 嘶~,不应该呀,我不是定义了imageTabBuildConfig了嘛?其实细心的朋友应该能发现,我在代码的问题处已经做了红框处理! 没错,就是这个object和by lazy导的鬼。
原因 众所周知,object的生命周期是跟随整个app的,而by lazy则是懒加载,在执行完一次后,后续获取的值都是用的第一次获取的值的缓存。这样看官们应该就能冥冥中悟到了:
假设:对照组账号为A(无图片tab),实验组账号为B 已知:A在进入搜索页后,未冷启,切换账号到B,再次进入搜索页 ps:切换账号后会自动从搜索页进入到首页 原因:A在懒加载没有图片tab对应的配置tabBuildConfigMap之后,后续切到账号B,一看tabBuildConfigMap已经获取到值了,那就直接拿就好啦,不会重新走实验来添加图片tab的Config。这就导致B命中了出图片tab,但实际配置项里却找不到对应的配置,那ViewPager自然就无法attach对应的Fragment上去了,于是才导致了崩溃。
解决方案 知道了问题的原因,对症下药就很简单了,解决方案无非就两个,任选其一即可:
- 将SearchResultTabs从静态object类型改成对象class类型,每次进入搜索页时就重新创建实例,那对应的tabBuildConfigMap就会在每次SearchResultTabs销毁时跟着一起销毁,从而by lazy只会在搜索页内生效,一旦进入首页,就需要重新获取,那就可以拿到实验配置项了
- 通过uuid来辨别用户是否切换了账号,如果是,则重新获取一次tabBuildConfigMap(采纳✅)
👀看文字长度就应该知道哪个方案简单些,很快啊,第二个方案就被采纳了,具体代码如下:
再运行一次,完美通过!