记一次与ReactNative纠缠的经历

昨天下班前给测试提交了一个测试版本,还没回到家就收到测试的微信,说这个版本的代码打包成的Android安装包在手机上一跑起来就崩溃。听到崩溃这词我轻松了一下,因为按照以往的经验来判断,此类问题一般是最容易解决的。不料想这个问题的解决过程有点像小时候田里挖地瓜一样,挖了一个还有一个,让人“惊喜连连”。特意写下这篇文章记录一下这个过程。

首先记录一下问题背景,以期日后我回来看这篇文章的时候依旧能回忆起整个故事的始末。

这次开发的产品使用ReactNative作为移动端的基础框架。由一个Web前端、一个Android前端、一个iOS前端一起开发。你可以想象为一个前端老手带俩半吊子学徒一起写一堆不三不四的代码。另外还有一个测试保证产品质量,工程师提交的代码将经过公司的自动部署工具Jenkins自动打包成可以运行的软件,供测试工程师安装测试。

我使用Mac进行开发,一般调试都在Mac上建虚拟机进行。此外手上还有两台Android手机,华为的Google Nexus 6P(6.0系统)、红米2(4.4系统)。

提交给测试的版本最后一次改动的内容是添加了支付宝的支付SDK,在Git上能找到该分支的代码。这还是收益于Git打标记打的清晰,不然代码都找不回了。

解决问题的过程比较曲折,三言两语难以道尽其中一波未平一波又起。总而言之,这是一个足够磨炼人的耐性的过程。说实在的,前端工程师的工作内容不外乎就是考验耐性的事儿。这件事上让我找回了一点继续混前端得自信。

回顾一下最初的问题:测试反馈Jenkins成功打包出软件但在手机上启动立即崩溃。

提交代码前是我是使用虚拟机测试过的,代码跑得很正常。于是我从Git上恢复了这部分的代码,在我的虚拟机上再跑了一次,发现还是没有问题。使用这份代码在我的电脑上编译成安装包,发现在Nexus和红米2上运行均出现崩溃。

查看Nexus的运行日志,提示是无法找到我自己写的一个非常简单的Android模块。我可以保证这个模块简单得不可能出错,它仅仅是向JS层暴露了几个关于应用的参数。既然不可能出错,那么只有可能是应用根本没有成功加载这个模块。于是我怀疑打包过程是有问题的。

经过几次实验,发现只要清除掉开发时保留的打包缓存文件,重新打包的时候就会失败。根据打包失败的日志,我发现打包时最后一个步骤所使用的支付宝开发文档提供的SDK混淆配置有问题,修改配置后可以继续正常打包。

新的安装包在虚拟机和Nexus上运行正常后我以为问题已经解决。可是在红米手机上依旧无法正常,而且这次启动崩溃得更快。由于一时间无法查看红米手机的日志,问题拖延到今天早上进行。

早上到公司继续解决问题。还是先印证了一下虚拟机的执行成果。发现在虚拟机和测试工程师手头上的手机运行均没有崩溃现象。这次验证又让我挖到了一个新的问题。经过登录页面后总会出现CPU占用过高,导致ReactNative的交互管理器无法正常回调。最后写这块代码的同事发现ReactNative循环动画会影响交互管理器。其实这个坑他以前有踩过一次,没想到这次又来了一次。

继续回到红米手机运行程序崩溃的问题。要解决这个问题必须要能查看红米手机的日志。这是我发现了小米公司比较流氓的地方了。希望小米看在我买了它那么多设备的分子上好好得给我躺这次枪。以前我使用百度找到了打开调试开关的方法并打开过的。不过因为最近更新了系统后被恢复成关闭状态,而且老方法也不好用了。最后还是花了好大功夫才解决了日志问题。我发誓再也不升级,同时也要吐槽一下小米最近推的澎湃芯片的广告,明明右下角有个跳过的按钮,为啥让我跳过的是正常页面进到你的广告页面,你是跟微博学的坏习惯?

看到了红米的日志,找到一个奇怪的关于水波效果背景的提示。想了很久才知道原来我们封装的按钮组件在Android上使用了原生的水纹效果的按钮。这个效果需要5.0以上的系统才支持,而封装这个组件的同事没有意识到这个问题。

到此崩溃问题解决了。继续回过头来想,我的电脑出现无法正常打包的现象,Jenkins也不应该能正常打包才对。向测试要了Jenkins的打包日志。果然证实了Jenkins根本没有成功打包,只不过它在编译代码失败后,执行下一个任务时使用了旧的缓存文件继续打包了个错误的安装包。修改Jenkins的配置,以防以后继续出现这样的问题。

这就是整个解决过程,也只不过是三段论的套路的嵌套使用罢了——观察问题、定位问题、解决问题,...

本来还有点模糊的,写下这么多文字后终于让我理清了整个过程。赞扬一下我的机智与勇敢:P

ChardLau

继续阅读此作者的更多文章