开发人员小c急匆匆跑来说见鬼了,App首页有个弹窗,在手机锁屏后再次解锁时弹窗就不见了,而且就是测试人员的小米手机上才出现,iPhone和其他Android手机没有这个问题。
看样子是个兼容问题,我先让他别急,先给重现问题演示给我看,然后看一下手机型号、系统版本。现场重现后,确实有问题,那么现在就来查找原因吧。
运行环境:小米5、Android 7.1
使用的是React Native提供的Modal
一、先看看其他Modal是否有问题
试验后发现其他的Modal运行正常,锁屏、解锁后依然正常显示
二、检查当前实现逻辑是否有问题
检查代码后发现一切正常,是按官方文档来实现的。怀疑是Android7上渲染有问题,但其他Modal又能正常显示。。。于是我们对比了一下两者的不同点。
三、发现疑点
其他的Modal是经过定制的,里面有一个gif图片,怀疑是gif图播放时强制触发了页面渲染。于是把gif图片移除,果然这些Modal也在Android 7的手机运行异常了。
四、怎么解决?
根据gif图片播放的启示,我们找到了一种解决办法,就是加个App活动状态监听,如果App进入active状态时,通过setState强制触发Modal渲染。
我们是自己封装了一个Modal,让它自己监听,自己刷新。
代码如下:
import * as React from "react";
import { AppState, Modal, Platform, ModalProps } from "react-native";
const isAndroid7 =
Platform.OS === "android" &&
(Platform.Version === 24 || Platform.Version === 25);
export default class ModalWrapper extends React.Component<ModalProps> {
state = {
appState: AppState.currentState
};
componentDidMount() {
if (isAndroid7) {
AppState.addEventListener("change", this.handleAppStateChange);
}
}
componentWillUnmount() {
if (isAndroid7) {
AppState.removeEventListener("change", this.handleAppStateChange);
}
}
handleAppStateChange = (nextAppState: any) => {
this.setState({ appState: nextAppState });
};
render() {
let { visible } = this.props;
const { appState } = this.state;
visible = isAndroid7 ? visible && appState === "active" : visible;
return (
<Modal {...this.props} visible={visible}>
{this.props.children}
</Modal>
);
}
}