首页 > 其他分享 >[转]Android冷启动白屏解析,带你一步步分析和解决问题

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

时间:2023-05-19 13:33:04浏览次数:45  
标签:Instant img gradle 冷启动 Run 白屏 Android


[img]http://dl2.iteye.com/upload/attachment/0118/3095/d8d8c13d-7225-33cd-9559-efcc6e1f9432.png[/img]
关于首次启动程序白屏时间过长这个问题其实我也早就发现了,而且正如评论中所说,有的时候白屏时间可以长达七八秒。

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

[b]问题重现[/b]

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

然后从这个时候开始,每次我们将程序安装到一台新手机上并首次启动时,都会经历一个很长的白屏时间,如下图所示:
[img]http://dl2.iteye.com/upload/attachment/0118/3097/1275c9c9-7a05-3606-b2e4-468efa4e63c9.png[/img]
上图中的播放速度是实时速度,没有经过加速或减速。可以看到,这就是一个空项目,里面几乎没有任何功能,首次启动白屏竟然持续了5秒钟左右!虽说只是首次启动才会白屏这么长时间,但给用户造成这样的体验,实在是显得我们的程序太业余了,因此必须要想办法解决一下。

[b]分析原因[/b]

一开始我将这个原因归结于是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,再运行程序的话就给弹出这样的提示:


[img]http://dl2.iteye.com/upload/attachment/0118/3099/6e2694c9-ef76-3193-b83b-c4fefd47177d.png[/img]


提示我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呀。



[b]解决问题[/b]



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



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


[img]http://dl2.iteye.com/upload/attachment/0118/3101/fbdbd486-102d-3fe5-8d6f-d92c373a1540.png[/img]


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



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



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



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



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


[img]http://dl2.iteye.com/upload/attachment/0118/3103/47dd7108-09b7-3441-999d-b87df966b37b.png[/img]


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



[b]进一步优化[/b]



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



这个就和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,就可以让程序在初始化的时候窗口是透明的,初始化结束后程序主界面才会显示出来,从而也就完全看不到白屏界面了,如下图所示:


[img]http://dl2.iteye.com/upload/attachment/0118/3105/a584c202-29ce-3aac-b2bb-a2a7f0e27f43.png[/img]


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


标签:Instant,img,gradle,冷启动,Run,白屏,Android
From: https://blog.51cto.com/u_15955464/6310677

相关文章

  • Android 有些机型不带tcpdump的解决办法
    输入mount命令[quote]mountrootfson/typerootfs(ro,relatime)tmpfson/devtypetmpfs(rw,relatime,mode=755)devptson/dev/ptstypedevpts(rw,relatime,mode=600)procon/proctypeproc(rw,relatime)sysfson/systypesysfs(rw,relatime)tmpfson......
  • Android 代码混淆proguard技术介绍
    由于各种反编译工具的泛滥,作为Android程序员在2.3版本以前只能通过手动添加proguard来实现代码混淆proguard这个工具是一个java代码混淆的工具在2.3版本的sdk中我们可以看到在android-sdk-windows/tools/下面多了一个proguard文件夹google已经把proguard......
  • Android Fragment完全解析,关于碎片你所需知道的一切
    我们都知道,Android上的界面展示都是通过Activity实现的,Activity实在是太常用了,我相信大家都已经非常熟悉了,这里就不再赘述。但是Activity也有它的局限性,同样的界面在手机上显示可能很好看,在平板上就未必了,因为平板的屏幕非常大,手机的界面放在平板上可能会有......
  • Android系统联系人全特效实现(下),字母表快速滚动
    其实ListView本身是有一个快速滚动属性的,可以通过在XML中设置android:fastScrollEnabled="true"来启用。包括以前老版本的Android联系人中都是使用这种方式来进行快速滚动的。效果如下图所示:[img]http://dl2.iteye.com/upload/attachment/0088/8223/48aec4c5......
  • Android 百度地图GPS获取定位经纬度
    首先进入百度地图官网,点击开发文档-->Android定位SDK-->获取密匙,进入应用创建界面,创建新的应用。准备好后,在“产品下载”栏目下载Android定位的包,将其打包放入项目中的libs文件目录。之后就需要在AndroidManifest.xml中添加APK,在Application标签中添加:<meta-dataand......
  • android vulkan
    VulkanAPIversionsandcapabilitiesThefollowingtablelistsVulkanAPIversionsforseveralAndroidreleases.AndroidVersionVulkanVersionAndroid13Vulkan1.3Android9Vulkan1.1Android7Vulkan1.0Vulkan1.3FunctionalityOverviewV......
  • Android 动态改变 navigation 的 startDestination, 使得已登录的用户直接跳过 LoginF
    需求:未登录用户打开App,会展示登录页面LoginFragment已登录用户打开App,直接展示MainFragmentnav_graph.xml结构如下:MainActivity.java:@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);......
  • 如何将抓包工具证书(cer,crt, pem)写入到Android系统内置根证书目录中实现 HTTPS 抓包
    0x01前言:在Android6之前,手机系统既信任系统内置的证书,也信任用户自己安装的证书,但是在Android7之后,却发生了变化,手机系统只信任系统内置的根证书。当然了,这是为了手机系统更安全,但是这样一来,我们就无法使用burpsuite,charles,fidder抓包app的HTTPS请......
  • 直播商城源码,Android实现监听Settings值变化的功能
    直播商城源码,Android实现监听Settings值变化的功能先创建一个内部类继承自ContentObserver   classSettingsContentObserverextendsContentObserver{    publicSettingsContentObserver(){      super(newHandler());    }    ......
  • 直播软件开发,Android实现根据进程名杀死特定进程
    直播软件开发,Android实现根据进程名杀死特定进程首先你实现功能的进程必须是系统进程,在AndroidManifest里面加入如下标签。 android:sharedUserId="android.uid.system"​调用ActivityManager的forceStopPackageAsUser方法 ActivityManagermActivityManager=(Activity......