Android中APP应用冷启动黑白屏原因 优化解决方案

版权声明:本文为博主原创文章,转载请标明出处 https://blog.csdn.net/qq_30993595/article/details/83791955

前言

做过APP开发,尤其是复杂项目的同学应该会经历过APP在桌面点击冷启动的时候,你以为会顺利打开应用首页,但是出现在你眼前的不是白屏就是黑屏的情况,也不会停留多久,可能就一闪而过;不管哪种情况,对于用户体验来说肯定是不行的,对于一个优秀程序员来说,怎么能看到自己开发的软件出现这种情况呢?那这到底怎么回事呢?今天就来说道说道

应用启动

应用启动一般分为冷启动,热启动

  • 冷启动:这其实是一个从无到有的过程,就是在启动应用前,系统中没有该应用的任何进程信息;比如启动设备后第一次启动这个应用,或者杀死该应用后再启动这个应用,这些情况都属于冷启动;这种启动方式所消耗的启动时间是最长的,所做的工作也是最多的
  • 热启动:这种就是启动应用前,系统中已经存在该应用的进程,比如你按back,home键回到桌面,再进入应用,这种情况就是热启动

我们今天要说的就是冷启动中出现的一些问题

冷启动流程

应该说冷启动是无法避免的,因为一个应用要想展示出来,它总是需要分配一定的内存等信息,而这些东西从无到有总是需要一定的时间,开发者能做的就是将这段等待时间尽可能优雅的给用户缩短或者隐藏起来

那冷启动过程到底发生了什么导致了这些并发症呢,说到这里就要阐述应用的启动流程了:

关于应用启动及进程创建可以参考这几篇文章
Android之Activity启动流程源码深入解析
解析Android中Zygote进程是如何fork一个APP进程
从Activity加载源码深入理解ActivityThrad的工作逻辑

当用户在Launcher内点击应用图标,Launcher将这个动作发送给AMS,AMS判断这个应用所在进程不存在,那就需要创建一个新的进程;然后AMS发送消息给Zygote进程,让它创建进程;Zygote进程经过一阵fork之后,分配好应用需要的内存,就通过反射加载ActivityThread类的main方法,接下来进入应用进程了;ActivityThread的main方法会创建应用的Application,加载主题,创建应用第一个Activity,加载布局,进行绘制显示,这样你就看到第一个Activity了,启动流程结束

问题原因

但是进程创建,类加载及Activity启动需要时间,如果啥都不做一直等到Activity渲染完显示,那这个空白期就很尴尬了,用户点了之后,啥都没反应,还停留在桌面,出现了假死现象,用户可能会再次点击,非常影响用户体验

于是Android就推出了一个预览窗口,应用一打开就显示这个窗口,给用户反馈,表明你点击有效;但是这个窗口展示什么呢?这时候Activity内容和layout都没加载完,别担心,因为此时Androidmanifest里面的信息已经读取到了,系统会将你在manifest文件设置的主题中android:windowBackground 属性来设置到DecorView中,你设置的是颜色,那就显示颜色;设置图片背景,那就显示图片;如果没有设置,那就默认是一个白屏或者黑屏

扫描二维码关注公众号,回复: 4129721 查看本文章

看到这里发现好像严格来说这不是问题,反而是个优化的结果;但是对于追求完美的程序猿来说,这种有损应用体验的情况怎么能存在呢,一定要解决

解决方法

  • 第一种

既然是这个预览窗口导致的黑白屏情况,那我们就禁用这个预览窗口,使用如下这个属性

<item name="android:windowDisablePreview">true</item>

这种做法虽然没有预览窗口了,但是会出现在桌面点击应用图标后,短暂停滞一段时间才打开APP

这个做法个人不推荐,直接把Google做的优化给取消了;但是我发现平时用的一些APP就是这种做法

  • 第二种

将背景设置透明

<item name="android:windowBackground">@android:color/transparent</item>

这种做法也不推荐,会出现点击图标后,到出现Activity内容是一个闪烁的过程;以及按home键回到应用列表也是一个闪烁的过程,影响用户体验

  • 第三种

将windowBackground属性设置成一张APP启动页一样的背景图,这样给用户的感觉是APP秒启动,因为预览窗口跟启动页几乎一模一样;如果启动页有其它后续加载的View,就会给人刷新不同步的感觉,不过市面上大部分应用启动页都是一个静态背景图,可以采用这种方法

<item name="android:windowBackground">@mipmap/img_app</item>

但是要注意,这里设置的背景图是常驻内存的,所以在离开预览窗口后,比如在欢迎页或者应用首页需要将背景图置null

getWindow().setBackgroundDrawable(null);

优化

上面说的几种方法都是很直接的,其实还有一些优化可以让预览窗口存在的时间更短点

  • 在开发应用的时候,基本上都会继承Application类,写一写自己的逻辑;熟悉应用启动流程的应该知道,应用启动后,是先回调Application的onCreate方法,然后再去加载Activity;但是我们在开发过程中难免会依赖一些第三方库或者组件,同时还会初始化一些资源等操作,这机会导致Activity的加载时间更加延后了

    所以这里就需要进行一些优化:
    比如不要做IO操作或者其它耗时操作,尽量不要执行太多静态数据操作,尽量不要做单例对象的初始化操作;反正能往后做的事情尽量别放到Application做

  • 对于Activity的布局,不要嵌套过多,影响绘制效率;过多的控件可以使用ViewStub,针对指定的业务场景,初始化指定的控件;在欢迎页尽量少做文件操作,比如数据库,SharedPreferences等

其实每个应用都有每个应用的特点,优化也不能以一概全,大家还是得根据自己的APP的特点去做针对性的处理

猜你喜欢

转载自blog.csdn.net/qq_30993595/article/details/83791955