Android应用冷启动解析和优化方案

前言

在我们点击Android手机桌面APP图标时,有时候我么会发现,应用并不是直接进入闪屏页或者应用主页面,而是会有一个短暂时间的白屏才能进去。但如果我们点击Back键退出应用,在点击返回的时候却没有白屏或者白屏时间几乎不可见。为什么会出现这种情况呢?这就涉及到Android应用冷热启动的问题。


启动方式

Android应用的启动方式可以分为三种:冷启动,暖启动,热启动;不同的启动方式表示着应用加载的方式不同,相对应的就产生了应用UI呈现给用户所需要花费的时间不同。


启动时间

Android 4.4(API 19)开始,Logcat可以自动打印出应用的启动时间,这个时间值从应用启动(创建进程)开始计算,到完成是视图的而第一次绘制(第一个Activity的界面第一次对用户可见)为止。



Cold Start (冷启动)

什么是冷启动? 比如设备开机后应用第一次启动,系统杀死应用进程(包括:用户主动杀死进程和系统内存吃紧引发的Kill)再次启动等。

在Android系统中,APP启动时,系统为每个运行的应用至少分配一个进程(多线程应用申请多个进程)。从进程角度讲,应该冷启动的时候,是没有该应用的进程配置信息的(包括 Application ,四大组件等),这样冷启动是所做的工作就会比其他两种启动方式多。


冷启动时,系统主要任务有两件:

1,开始加载并启动APP;

2,创建应用进程信息,进入并显示第一个Activity UI。

而我们我看到的白屏就是在第二步,配置进程信息和第一个Activity UI渲染到页面之前所花费的时间。那么我们来分析一下系统创建应用进程后,所要处理的事情;

1,初始化应用中的对象(比如Application的创建及其onCreate中的工作)

2,启动主线程;

3,创建第一个Activity;

4,加载布局视图(Inflating);

5,初始化控件在屏幕上的位置(Laying out)

6,绘制视图(draw)

只有当应用完成第一次绘制,系统当前展现的空白背景才会被Activity的布局视图替换掉。这是用户才能应用进行交互。在这个流程中主要涉及到Application 的onCreate和第一个Activity的onCreate方法,它们均在View绘制展示之前进行处理。所以在应用自定义的Application类中和第一个Activity类中的onCreate方法处理的逻辑越多,冷启动花费的时间就越长。


Warm Start (暖启动)

当APP中的Activities被销毁,但在内存中常驻时,应用的启动方式就会变为暖启动。相比于冷启动,暖启动过程减少了对象的初始化,布局加载等工作,启动时间会缩短。但启动时,系统忍让会展现一个空白背景,直到第一个Activity的内容替换。


Lukewarm Start (热启动)

热启动产生的场景有很多,比如:用户点击Back键退出应用,然后马上就重新启动。这是布局依旧是之前绘制好的,所以花费的时间更少。


优化方案

应用的冷启动是无法避免的,也就是说冷启动时用户总需要经历一个等待启动时间。开发人员唯一能做的就是在 Application 和 第一个 Activity 中,减少 onCreate() 方法的工作量,从而缩短冷启动的时间。像应用中嵌入的一些第三方 SDK,都建议在 Application 中做一些初始化工作,开发人员不妨采取懒加载的形式移除这部分代码,而在真正需要用到第三方 SDK 时再进行初始化。

除此之外,还有一种方式就是通过设置应用主题背景的方法,把应用默认展现的白色背景替换被透明背景。我们新建一个主题样式:

   <style name="LaunchStyle" parent="AppTheme">
        <!--设置透明背景-->
        <!--<item name="android:windowIsTranslucent">true</item>-->
        <!--设置无标题-->
        <!--<item name="android:windowNoTitle">true</item>-->
    </style>
然后在AndroidManifast.xml文件中将主题设置给第一个启动的Activity

<application
    android:name=".MyApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true">
    <activity
        android:name=".MainActivity"
        android:theme="@style/MyStyle">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
然后在修改MainActivity的onCreate中,在setContentView(R.layout.avtivity_main)加载布局之前把主题修改回来

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTheme(R.style.AppTheme);
        setContentView(R.layout.activity_main);
    }

我们可以看到现在白屏是没有了,这是应为我们将应用主题背景设置为透明,在我们点击应用图标之后,其实就已经打开了应用,不过此时应用背景为透明,我们让看到的是桌面。虽然这样做白屏是没有了,但是我们可以明显看到应用打开呈现一种卡顿延迟的现象。这种效果相比于白屏更不可取(这是因为我在Aplication的onCreate方法中休眠了三秒)

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


除了上边这种方法,还有一种更好的解决思路。就是通过android:windowBackground" 设置自定义主题背景,这样就给到用户一种很好的视觉过渡效果。可以参考优酷APP效果,直接将原本展示白屏的页替换成应用的闪屏页。

<style name="LaunchStyle" parent="AppTheme">
        <!--设置Appliction背景-->
        <item name="android:windowBackground">@drawable/layout_launch</item>
</style>


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

    <item android:drawable="@color/color_white" />
    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/baidu" />
    </item>

</layer-list>


这是最终的效果,当然如果添加些动画效果会更好。






猜你喜欢

转载自blog.csdn.net/ding_gc/article/details/53198837