文档章节

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

abcijkxyz
 abcijkxyz
发布于 2016/07/30 17:29
字数 2006
阅读 5
收藏 0

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/51019856

本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新。

写在前面

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

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

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

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

问题重现

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

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

上图中的播放速度是实时速度,没有经过加速或减速。可以看到,这就是一个空项目,里面几乎没有任何功能,首次启动白屏竟然持续了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的工作原理图来体验一下:

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

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

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

但是大家有没有想过Instant Run是用来做什么的?是用来提升开发效率的,没错,就是开发效率!也就是说,只有在开发阶段才会有Instant Run这个东西,在正式的产品中是完全不存在Instant Run的!

是不是一语点醒梦中人了?其实说白了,我们担心这个长时间白屏会损伤用户体验纯粹是在杞人忧天,Google早就帮我们都考虑过了,release版的程序是不会出现这种现象的。不信的话我现在就打一个签名后的APK包,然后我们装到手机上试一下,如下所示:

这和刚才是一模一样的程序,我没有修改任何的代码,只是打了一个release包,现在就没有长时间白屏的情况了。

进一步优化

如果你的观察力非常敏锐的话,应该能发现其实我们的程序还是会经历一个白屏的阶段,只不过非常短,瞬间就跳过了。

这个就和Instant Run无关了,这是由于在启动的时候程序都要进行一些基本的初始化操作,所有程序都是要经历这个过程的。

虽说这个白屏时间很短,并没有什么太大的影响,不过我们还是可以通过代码来进一步优化的。修改styles.xml中主题相关的代码,如下所示:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> ...... <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style>

其中我们加入了两个属性,windowIsTranslucent和windowNoTitle,将这两个属性都设置成true,就可以让程序在初始化的时候窗口是透明的,初始化结束后程序主界面才会显示出来,从而也就完全看不到白屏界面了,如下图所示:

使用这种方式,虽然白屏界面看不到了,但是由于初始化的过程中窗口是透明的,会让用户感觉程序启动的响应速度稍微慢了点,不过其实这种差别都是毫秒级的,就没必要再为这个担心了。


关注我的微信公众号,每天都有优质技术文章推送,你还可以向公众号投稿,将自己总结的技术心得分享给大家。
扫一扫下方二维码或在微信搜索 郭霖 即可关注:

本文转载自:http://blog.csdn.net/guolin_blog/article/details/51019856

共有 人打赏支持
abcijkxyz
粉丝 63
博文 6196
码字总数 1876
作品 0
深圳
项目经理
私信 提问
Android 跨进程启动Activity黑屏(白屏)的三种解决方案

原文链接:http://blog.csdn.net/feiduclear_up/article/details/78822775 当Android跨进程启动Activity时,过程界面很黑屏(白屏)短暂时间(几百毫秒?)。当然从桌面Lunacher启动一个App...

废墟的树
2017/12/17
0
0
一步步拆解 LeakCanary

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 java 源码系列 - 带你读懂 Reference 和 ReferenceQueue https://blog.csdn.net/gdutxiaoxu/article/details/80738581 一步步拆解 ...

xujun9411
07/04
0
0
【必看】Android干货整理

哗啦啦,为方便大家更好的学习交流,小编特地整理了一大波干货!预备 前方高能预警,一大波干货袭来,接住了!!!!!!!!!!!! 如果你是零基础小白,不知如何上手Android开发,不知应学习哪些工具...

慕课网官方_运营中心
08/01
0
0
Android 启动APP时黑屏白屏的解决方案

在开发中,我们在启动app的时候,屏幕会出现一段时间的白屏或者黑屏,不同设备时间长短不同。很影响用户体验。 首先分析一下,产生这个现象的原因,当我们在启动一个应用时,系统会去检查是否...

记录自己的点点滴滴
07/20
0
0
Android模拟器如何异型屏

前言 Android Studio 3.1 稳定版已发布,重点围绕产品质量和应用开发效率进行改进。 详细请看Android Studio 3.1新特性介绍 由于我是那种爱折腾的人,第一眼看见的不是D8不是Kotlin Lint 检查...

no白菜
04/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Supplier函数式接口

Supplier接口的不传入参数,返回一个值。真是一个无私奉献的接口,还没有default方法。 下面就想用一个接口试试,其实我本来用的是IntSupplier,但是发现在使用方法引用的时候,不好把Math....

woshixin
11分钟前
0
0
MyBaties一级缓存

一、一级缓存简介 在系统代码的运行中,我们可能会在一个数据库会话中,执行多次查询条件完全相同的Sql,鉴于日常应用的大部分场景都是读多写少,这重复的查询会带来一定的网络开销,同时sel...

嘴角轻扬30
18分钟前
0
0
jquery

语法 描述 实例 $("*") 选取所有元素 在线实例 $(this) 选取当前 HTML 元素 在线实例 $("p.intro") 选取 class 为 intro 的 <p> 元素 在线实例 $("p:first") 选取第一个 <p> 元素 在线实例 ...

mskk
24分钟前
1
0
微信红包设计方案

前言 微信红包一经推出,春节期间微信用户红包总发送量达80.8亿,红包峰值40.9w/秒,在如此量级下,系统设计存在各种变数,稍有闪失会功亏一篑。 红包系统 红包系统有三部分组成:信息流,业...

春哥大魔王的博客
34分钟前
1
0
微信开发-正式号的配置

1、设置相关 业务域名的设置(不设置的话,相关页面会显示防欺诈盗号信息提示) JS接口安全域名设置 网页授权域名设置 注意:以上三个设置中都有下载文件的提示,此文件内容一样,下载一个即可...

Code辉
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部