问题场景:采用ionic3开发的App,当项目比较大的时候,会出现部分真机设备在启动的过程中有白屏或黑屏的情况。
原因预测:个别手机,尤其是安卓手机的性能比较差,App在启动后进入首页或登录页前的初始化工作还没有完成。
方案总结:在网上查过很多资料发现大部分的解决办法都是简单的分为两种:1、自动关闭启动页;2、设置具体的毫秒后手动关闭启动页;
但是,仍然会有部分项目部分手机还是无法解决这个问题,当你看到这篇文章的时候,很有可能以上两种方案都不适用。
进一步分析原因: 我们无法准确评估自己的App启动在不同的设备上启动到底需要多长时间,所以从理论上说当问题出现的时候,无论是简单的自动关闭还是手动关闭都是不可取的,踩过大量的坑之后,思路终于转变了下。
终极解决方案:让程序去自动检测应用在当前设备每次启动的初始化完毕的时间点,在恰好合适的时刻去关闭启动页再进入首页或登录页。
以下是我的项目中的具体实现代码:
let isStartByHand: boolean = true; // 是否手动关闭启动
if (!isStartByHand) { // 自动关闭
platform.ready().then(() => {
statusBar.styleDefault();
splashScreen.hide();
});
} else { // 手动关闭
let startTime = new Date().getMilliseconds(); // 调试用
var isCleared: boolean = false;
let timeOut = 2000, count = 0; // 记录自动检测的次数,不断地寻找合适的时间节点
let interval = setInterval(()=>{
if (SplashScreen.installed() && Camera.installed() && File.installed() && AppVersion.installed() && ScreenOrientation.installed()) {
console.log("SplashScreen已经安装完毕=====interval=====" + "时间差毫秒值:" + (new Date().getMilliseconds()-startTime));
// 防止出现1~2秒钟的白屏,再次延迟隐藏启动页
setTimeout(() => {
clearInterval(interval);
splashScreen.hide();
isCleared = true;
}, timeOut + 1000 + count++ * 1000); // 加1000错开定时任务延时
}
},timeOut);
// 防止启动时间不够出现闪屏(在首页与启动页之间频繁切换)
setTimeout(() => {
if (isCleared) {
clearInterval(interval);
}
}, timeOut);
platform.ready().then(() => {
// 初始化访问量服务
GlobalVariables.appVisitCountService = appVisitCountService;
// App装机量统计
appInstalledService.checkAndSendInstalledInfo();
// 强制检验更新
this.checkVersionUpdate();
clearInterval(interval); // 如果实际启动较快,通过正常关闭启动页,则清除定时任务
console.log("========全部插件已经安装完毕=====ready.then=====" + "时间差毫秒值:" + (new Date().getMilliseconds()-startTime));
statusBar.styleDefault();
splashScreen.hide();
this.isIphoneX(platform);
this.isDevice(platform);
// 自动登录
this.autoLogin();
});
}
备注:如果复制代码套用后发现偶尔出现应用在启动页和首页(或登录页)之间来回切换的问题,则需要调试更改时间参数。
后记:经过大量的反复试验,特别是采用出现启动问题的真机,不断地调试,修改定时和延时任务的时间参数,达到均衡合理的状态,终于把能用的团队手机都适配了,目前上线5个月了没有出现过启动白黑屏的问题。