[Android从头再来] App启动过程

App启动方式

如何启动App呢?
说到底就是点击屏幕的App图标。但是点击的时候会发现有时进入App首页很快,有时很慢,有时中间还有个白屏。有时中间还有个黑屏。
造成这样的情况,是什么原因呢?我们先从App启动的方式开始说起。

冷启动
热启动

冷启动

冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用。

冷启动的特点:因为系统会重新创建一个新的进程分配给它,所以会创建和初始化Application,在创建和初始化它的Launch Activity(onCreate onMesure onLayout,ondraw),最后展示在界面上

热启动

热启动:当启动应用时,后台存在该应用的进程(back键,home键,应用退出,但是没有销毁),从已有的进程中启动

热启动的特点:从已有的进程中启动,不需要创建和初始化Application ,直接创建和初始化它的Launch Activity

<mark>两者区别:后台进程是否存在相应的进程,创建进程是耗时操作</mark>

应用的启动过程

主要讲解冷启动的情况(分配进程->创建和初始化Application->创建和初始化Launch Activity)

可以参考老罗的Android之旅-Android应用程序启动过程源代码分析

我这里做了下摘要,App启动过程就是:

整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段:

一. Step1 - Step 11:
Launcher通过Binder进程间通信机制通知ActivityManagerService,
它要启动一个Activity;

二. Step 12 - Step 16:
ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;

三. Step 17 - Step 24:
Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,
于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,
即将要启动的Activity就是在这个ActivityThread实例中运行;

四. Step 25 - Step 27:
ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,
以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;

五. Step 28 - Step 35:
ActivityManagerService通过Binder进程间通信机制通知ActivityThread,
现在一切准备就绪,它可以真正执行Activity的启动操作了。

<mark>有兴趣可以看下源码实现,其实App的启动相当于在Launch 这个应用中点击某个图标进行跳转</mark>

ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例 –可以理解成Zygote进程中fork一个新的进程分配给应用.至于Zygote是什么呢?我还没搞懂呢。推荐两篇博客大家自行理解下
Android深入浅出之Zygote

Android系统进程Zygote启动过程的源代码分析
后续理解了,会专门讲解下

如何测量应用启动时间

  1. 可以通过代码打桩,计算启动时间
  2. 可以通过秒表计算(肉眼观察,这个很low)

最近查到资料,android是有命令可以计算启动时间的

adb shell am start -W [packageName]/[packageName.launchActivity]

OK,那就拿自己的项目来给大家看看上面两种启动的时间差别

冷启动:

《[Android从头再来] App启动过程》 冷启动

热启动

《[Android从头再来] App启动过程》 热启动

<mark>两者差距时间很多,只能说明在Application做了很多耗时的操作.并且现在大部分的App启动是冷启动,因为用户的习惯就是不喜欢有这么多后台进程,他们喜欢删掉所有进程

提醒:
<mark>避免一些耗时操作在Application中处理,并减少LaunchActivity的View层级,减少View测量绘制时间

App启动为什么会白屏,黑屏

回到刚开始的问题,为什么有时打开App会出现白屏/黑屏情况

先来解释下为什么会出现白屏/黑屏的原因?

是因为已进入到Activity,但是未加载到布局文件,
就先显示来windows窗口的背景。
黑屏/白屏就是显示的windows背景(这个就是theme的设置)

解决方案:

1.为 Theme 设置背景图;
(会给人一种快速加载的感觉)
<style name="Theme.AppStartLoad" parent="android:Theme">  
    <item name="android:windowBackground">@drawable/ipod_bg</item> 
    <item name="android:windowNoTitle">true</item>  
</style>

2.为 Theme 设置透明属性
(回给人较慢加载出来感觉,因为需要等布局加载完之后一次性展开)
<style name="Theme.AppStartLoadTranslucent" parent="android:Theme">  
    <item name="android:windowIsTranslucent">true</item> 
    <item name="android:windowNoTitle">true</item>  
</style>

这里不展开了,可以看下这个Android开发之解决APP启动白屏或者黑屏闪现的问题

优化冷启动时间的小技巧

按照刚才说的为什么出现白屏/黑屏原因的解决方案。

其实可以在给启动的Activity的Theme中背景设置为启动页的图片,然后在等待加载完activtity的布局后,恢复原来的theme

代码举例:

在style.xml文件

 <style name="AppTheme.Launcher">
     <item name="android:windowBackground">@drawable/appstart_background
     </item>

        <!--<item name="android:windowIsTranslucent">true</item>-->
    </style>

在AndroidManifest.xml

  <activity android:name=".AppStartActivity"
            android:theme="@style/AppTheme.Launcher">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

AppStartActivity.java

public class AppStartActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        setContentView(R.layout.activity_appstart);
    }
}

上面的@drawable/appstart_background就是启动页的默认背景。亲测,可用

相关链接

android 性能优化 — 启动过程 冷启动 热启动

Android 冷启动 热启动 测试

消除 activity 启动时白屏、黑屏问题

Android开发之解决APP启动白屏或者黑屏闪现的问题

    原文作者:乱码桑
    原文地址: https://www.jianshu.com/p/e69d22ec0582
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞