close
当前位置: 物联网在线 > 技术文库 > android >

Android冷启动白屏解析,带你一步步分析和解决问题

记得在本月初,我发表了一篇文章叫《 Android Studio新功能解析,你真的了解Instant Run吗?》,里面详细讲解了Android Studio中新加入的Instant Run功能,使得我们开发的效率可以大大地提升。

不过对于这个功能也有不少朋友提出了疑问,比如我在我的博客评论区就看到了这样的评论:

Android冷启动白屏解析,带你一步步分析和解决问题

关于首次启动程序白屏时间过长这个问题其实我也早就发现了,而且正如评论中所说,有的时候白屏时间可以长达七八秒。

看来这个问题已经是一个普遍存在的现象了,可能很多人对此都产生了疑惑。那么这里我就专门写一篇文章来为大家答疑解惑吧。

问题重现

我初次发现这个问题是在升级了Android Studio 2.0之后,当时Android Studio的版本是从1.5直接升级到了2.0,一个如此大版本的跨跃说明改动肯定是比较大的。

然后从这个时候开始,每次我们将程序安装到一台新手机上并首次启动时,都会经历一个很长的白屏时间,如下图所示:

Android冷启动白屏解析,带你一步步分析和解决问题

上图中的播放速度是实时速度,没有经过加速或减速。可以看到,这就是一个空项目,里面几乎没有任何功能,首次启动白屏竟然持续了5秒钟左右!虽说只是首次启动才会白屏这么长时间,但给用户造成这样的体验,实在是显得我们的程序太业余了,因此必须要想办法解决一下。

分析原因

一开始我将这个原因归结于是Android Studio 2.0的bug,毕竟一次性做了这么大的升级,有点bug也是很正常的。但是直到现在最新的Android Studio 2.2版本,这个问题依然还存在,好像Google完全就没有修复它的意思,这就不太对劲了。

然后我开始动手做实验,发现这个长时间白屏的问题其实和Android Studio的版本是没有关系的,而是和我们使用的gradle插件版本有关系。打开build.gradle文件查看一下,代码如下所示:

buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.1.2' } }

可以看到,这里我使用的gradle插件版本是2.1.2,这个版本下是会出现长时间白屏的问题的。

但如果我将gradle插件的版本号降低,比如降到2.0.0,再运行程序的话就给弹出这样的提示:

提示我2.0.0版本的gradle插件是不支持Instant Run的,让我升级到2.1.2。但同时你会发现,长时间白屏的问题不见了。

但这里我还要再专门说明一下,其实并不是2.0.0版本的gradle插件不支持Instant Run,而是因为我当前使用的是2.1版的Android Studio,它和2.0.0版本的gradle插件在Instnat Run功能方面不兼容。如果你是使用的2.0版本的Android Studio,那么你会发现2.0.0版本的gradle插件也是支持Instant Run的。

如果你有兴趣的话可以把gradle插件的版本号再改低一些,比如1.5.0,或者1.3.0,这两个插件版本就是完全不支持Instant Run功能了,你会发现它们都不会造成长时间白屏的问题。

这样我们基本就把问题的原因定位出来了,支持Instant Run功能的时候就会出现长时间白屏的情况,不支持Instant Run功能的时候就一切正常,看来罪魁祸首果然还是Instant Run呀。

解决问题

但是Instant Run是Android Studio 2.0中重磅推出的功能,如果存在这么严重的bug,那么谁还敢使用呢?Google岂不是推出了一个废功能?

当然不是,遇到这个问题就吓得不敢用Instant Run的话,只能说明你对Instant Run功能没有真正理解。Instant Run为了能够让我们快速部署代码,背后其实是有一套非常复杂的逻辑的,比如要在APK中建立服务器与Android Studio进行通信,以及代码差异比对和替换等,这里给大家贴一张Instant Run的工作原理图来体验一下:

Android冷启动白屏解析,带你一步步分析和解决问题

这张图比较复杂,看不懂也没关系,因为我也看不懂,但是至少这让我们能直观地感受到Instant Run背后处理的工作是非常繁重的。

既然如此,相信大家也应该理解一下为什么首次启动会白屏这么长时间,因为为了要让Instant Run可以正常工作,我们的程序需要做非常多的初始化工作。而这一次的长时间白屏,换来的却是后续开发效率的剧增,这个交易我认为是相当值得的。

那有的朋友可能就要产生质疑了,说我们理解有什么用呀?用户又不会理解什么是Instant Run,这么久的白屏是会严重损伤用户体验的。


(责任编辑:ioter)

用户喜欢...

Android Weekly #276 安卓开发周刊 中文版

您是否了解过Android的Lifecycle-Aware库?(android.jlelse.eu) 我们如何了解Lifecycle-Aware库代码? Nishant Srivastava展示了可以跟踪活动或Lifecycle-Aware的Lifecycle Arch组件的片段,并相应地调整其行为。 为Mos...


Android Weekly #275 安卓开发周刊 中文版

MapMe — Android地图适配器 (medium.com) Josh Burton介绍MapMe,是一个用Kotlin编写的Android库,可以将适配器模式带到地图上。 赞助 CloudRail - 连接到API 10x更快 (cloudrail.com) 当我们用单一的界面连接到所...


使用Android Studio开发可独立运行(runnable)混淆过的Jar程序

之前开发Java程序一直都是使用Eclipse 开发Jar程序,现在开发基本上都已经弃用Eclipse了,但是有时偶尔开发个小的Jar程序,还要切换回去好麻烦,刚好前几天有人问几个相关的问题,就顺便整...


Android Weekly #274 安卓开发周刊 中文版

探索Android Oreo上的别后执行限制(medium.com) 在这篇文章中,Joe Birch解释了关于Android Oreo在后台运行服务的变化。 non-Time领主的time – 第5部分 (blog.stylingandroid.com) Mark Allison继续分析JSR 310 date和...


Android Weekly #273 安卓开发周刊 中文版

开源你的Android代码(android.jlelse.eu) 通过您的开源Android代码,您将(希望地)为Android社区提供有价值的代码,收到建设性的反馈,并与您最初建立的内容进行协作从而使您的代码变得更好。这...


Android Weekly #272 安卓开发周刊 中文版

Android Dev 101:每个初学者都应该知道的一些做法() 看一些初学者或媒介等级开发人员(不要错过任何人)应该知道的一些做法,以便更好地摆脱Android框架。 99.9% crash free sessions (medium.com) Chr...


Android Weekly #271 安卓开发周刊 中文版

依赖注入检查(medium.com) 在本文中,MihályNagy引入了依赖注入检查,一种开源注释处理器,可帮助您解决一些出现在所有JSR 330 DI库中常见的问题。 使用Android Studio插件提高效率 (blog.mindorks.com...


Android Weekly #270 安卓开发周刊 中文版

带有RxJava2的SOLID Android分析 (medium.com) 在这篇文章中,Aris Papadopoulos将解释如何正确创建一个分析系统,同时遵循SOLID原则,并使用RxJava2来解决问题。 (blog.stylingandroid.com) Java中的编程时间很难...


Android内存泄漏思考

Android内存泄漏是一个经常要遇到的问题,程序在内存泄漏的时候很容易导致OOM的发生。那么如何查找内存泄漏和避免内存泄漏就是需要知晓的一个问题,首先我们需要知道一些基础知识。...


Android Weekly #269 安卓开发周刊 中文版

在Google上快速提出操作 () Wolfram Rittmeyer分享了开始在Google上快速创建操作所需的所有信息(为了家庭与助理)。 RxJava中的错误处理(rongi.github.io) 一旦开始编写RxJava代码,你就会意识到有些事...