天天看点

Android首次启动黑屏白屏优化(windowBackground)

有关于Android第一次启动出现的黑屏和白屏的过渡问题,看了很多相关的资料和文章,决定将自己的一些见解和处理方式总结一下,以便日后在遇到有个思路,先大致列为几个部分。

一:应用点击启动的过程描述和冷热启动的概念

手机本身的桌面也是一个应用,所有的应用图标在桌面上的点击事件就像是应用中的控件OnCLick点击事件一样,都是处于用户点击的时候监听的状态,一个应用在桌面上被用户点击之后到启动是一个复杂的过程,对这个过程描述比较详细的文章:https://blog.csdn.net/qian520ao/article/details/78156214可供参考。大致过程就是

1、Launcher通知AMS启动APP的MainActivity,也就是清单文件设置启动的Activity。

2、AMS记录要启动的Activity信息,并且通知Launcher进入pause状态。

3、Launcher进入pause状态后,通知AMS已经paused了,可以启动了。

4、app未开启过,所以AMS启动新的进程,并且在新进程中创建ActivityThread对象,执行其中的main函数方法。

5、app主线程启动完毕后通知AMS,并传入applicationThread以便通讯。

6、AMS通知绑定Application并启动MainActivity。

7、启动MainActivitiy,并且创建和关联Context,最后调用onCreate方法。

在这里要插入一个概念,在启动整个应用的过程中,就会因不同情况出现冷启动和热启动两种,冷启动就是在启动该应用前,系统中没有该应用的任何进程信息。 (第一次打开应用、杀死了进程再打开、时间最长)热启动则是用户使用返回键推出应用,然后马上又重新启动应用。二者的区别是冷启动没有创建过初始化,热启动是已经初始化再打开。

二:为什么会首次加载出现白屏或者黑屏的效果

说完启动过程,就要来说明一下为什么会出现白屏或者黑屏的问题。在应用冷启动和热启动的过程中,总归是要创建这个应用进程的,所以在这个过程中Google为了增加用户的体验,就做了一个过渡效果的Windows窗口,这个Windows窗口效果根据你设定的启动页面的主题来显示,如果你设置的主题是Light则过渡窗口是默认白屏,反之则是默认黑屏,当应用第一次加载打开或者进程被杀死重新启动的时候(冷启动),那么这个过渡窗口就会显示较长时间,热启动则会一闪而过,总之黑屏和白屏的产生,就是这样来的

三:如何去优化这个过程

优化的方法网上有很多,经过每个方法的尝试和实践测试,有一个自己的方式来实现,另外结尾会归纳一下其他几种方式不采纳的原因

我的方式是通过设置

Style.Xml主题

<!-- 启动页主题 -->
<style name="StartAppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
    <item name="android:windowBackground">@drawable/xxxxx</item>
    <item name="android:windowIsTranslucent">false</item>
</style>      
设置清单文件AndroidManifest.Xml
<activity
    android:name=".activity.xxxxxActivity"
    android:label="@string/xxxxx"
    android:screenOrientation="portrait"
    android:theme="@style/StartAppTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>      

引用xxxxx的drawable文件

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:bottom="xxxdp">
        <color android:color="#ffffff" />
    </item>
    <item>
        <color android:color="#ffffff" />
    </item>
    <item android:bottom="xxxdp">
        <bitmap
            android:gravity="bottom|center_horizontal"
            android:src="@drawable/你的logo图片" />
    </item>

    <item android:bottom="xxxdp">
        <bitmap
            android:gravity="bottom|center_horizontal"
            android:src="@drawable/你的logo图片" />
    </item>

</layer-list>
      

这里之所以用自定义的drawable,是因为我们没有现成的启动图片,而且为了和随后启动的广告页面保持一致,所以采用了一个白背景加Logo底的自定义效果,这样当广告页加载的时候可以平稳无差别过渡。关于Android中layer-list使用,也可以搜到大部分文章,这里只简单讲一下layer-list是将多个drawable按照顺序层叠在一起显示,默认情况下,所有的item中的drawable都会自动根据它附上view的大小而进行缩放,

layer-list中的item是按照顺序从下往上叠加的,即先定义的item在下面,后面的依次往上面叠放。所以有了如上的自定义Drawable效果

附:

使用方案

<item name="android:windowIsTranslucent">true</item>将过渡窗口设置成无,即透明效果,这种方式如果遇到手机硬件配置好的情况,可能会平稳启动应用,并且无黑屏闪显,但是如果遇到配置很差的手机,会出现用户点击后卡在原地很久才打开应用的错觉,其实只是过渡效果透明了,所以为了不影响用户体验,还是建议不使用
      

使用方案

<style name="StartAppTheme" parent="@android:style/Theme.NoTitleBar.Fullscreen">
    <item name="android:windowBackground">@drawable/图片</item>
    <item name="android:windowIsTranslucent">false</item>
</style>      

虽然可以用一张图片替换过渡效果,并且效果不错,但是如果启动页和该图片有大的出入,会给用户一种视差,不能起到平稳过度的感觉

使用方案

getActivity().getWindow().getDecorView().setBackground(new BitmapDrawable(blurBitmap));

动态去替换过渡页,没有尝试过,不过感觉过渡界面本身没那么复杂多变,而且将动态设置放在执行类中,也担心可能无效,所以并没做过多尝试

继续阅读