# Android 启动白屏

为什么会出现启动白屏?
先来了解两个概念:

  • 冷启动
  • 热启动

# 冷启动

当前要启动的App 没有驻留在系统后台 这时启动 app 需要从头挂起服务 系统创建一个新的进程给该应用初始化走流程

# 热启动

当前要启动的App 系统已有该应用 (举个栗子:按下 back键 退出程序 、home键 回到后台 )该应用的进程还是保留在后台任务中

# 冷启动 热启动的区别

冷启动:系统没有该应用的进程,需要创建一个新的进程分配给应用,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。
热启动: 从已有的进程中来启动,不会创建和初始化Application类,直接创建和初始化MainActivity类(包括一系列的测量、布局、绘制),最后显示在界面上。

# 冷启动时间计算

API19 之后,系统会出打印日志输出启动的时间;
冷启动时间 = 应用启动(创建进程) —> 完成视图的第一次绘制(Activity内容对用户可见);

# 冷启动流程

Zygote进程中fork创建出一个新的进程;
创建和初始化Application类、创建MainActivity;
inflate布局、当onCreate/onStart/onResume方法都走完;
contentView的measure/layout/draw显示在界面上;
总结:
Application构造方法 –> attachBaseContext() –> onCreate() –> Activity构造方法 –> onCreate() –> 配置主题中背景等属性 –> onStart() –> onResume() –> 测量布局绘制显示在界面上

# 冷启动的优化

减少在Application和第一个Activity的onCreate()方法的工作量;
不要让Application参与业务的操作;
不要在Application进行耗时操作;
不要以静态变量的方式在Application中保存数据;
减少布局的复杂性和深度;

# 解决方案

将 Application onCreate() 方法中一些耗时的初始化 方法 放置 IntentService 中 开启一个服务
设置启动页主题 Theme
推荐:

<style name="StartTheme" parent="Theme.AppCompat.Light">
    	<!--启动页背景-->
        <item name="android:windowBackground">@drawable/shape_start_pg</item>
        <item name="android:windowNoTitle">true</item>
        <!--设置全屏模式-->
        <item name="android:windowFullscreen">true</item>
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
# 防止启动页拉伸变形 适配
  • layer-list
    在brawable 文件夹下 新建 layer-list 图层
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
   		<!--背景色-->
        <shape>
            <solid android:color="@android:color/white" />
            <size
                android:width="360dp"
                android:height="640dp" />
        </shape>
    </item>
    <!--启动页Logo 放置位置-->
    <item
        android:bottom="295dp"
        android:left="90dp"
        android:right="90dp"
        android:top="150dp">
        <bitmap
            android:gravity="top"
            android:src="@drawable/icon" />
    </item>
</layer-list>

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.huifeideyema.splash">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:theme="@style/StartTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>