Android应用启动流程


一、启动

1.1、冷启动和热启动

  • 冷启动:当启动应用时,后台没有该应用的进程,这时系统会重新创建一个新的进程分配给该应用,然后再根据启动的参数,启动对应的进程组件,这个启动方式就是冷启动。
  • 热启动:当启动应用时,后台已有该应用的进程(例:按back键、home键,应用虽然会退出,但是该应用的进程是依然会保留在后台,可进入任务列表查看),所以在已有进程的情况下,这种启动会从已有的进程中来启动对应的进程组件,这个方式叫热启动。

1.2、启动架构图:

在这里插入图片描述

1.3、启动流程

①点击桌面App图标,Launcher进程采用Binder IPC向system_server进程发起startActivity请求;

②system_server进程接收到请求后,向zygote进程发送创建进程的请求;

③Zygote进程fork出新的子进程,即App进程;

④App进程,通过Binder IPC向sytem_server进程发起attachApplication请求;

⑤system_server进程在收到请求后,进行一系列准备工作后,再通过binder IPC向App进程发送scheduleLaunchActivity请求;

⑥App进程的binder线程(ApplicationThread)在收到请求后,通过handler向主线程发送LAUNCH_ACTIVITY消息;

⑦主线程在收到Message后,通过发射机制创建目标Activity,并回调Activity.onCreate()等方法。

⑧App便正式启动,开始进入Activity生命周期,执行完onCreate/onStart/onResume方法,UI渲染结束后便可以看到App的主界面。
在这里插入图片描述


二、主要类介绍

2.1、zygote

zygote意为“受精卵“。Android是基于Linux系统的,而在Linux中,所有的进程都是由init进程直接或者是间接fork出来的,zygote进程也不例外。

Android系统zygote是一个进程的名字。Android是基于Linux System的,当你的手机开机的时候,Linux的内核加载完成之后就会启动一个叫“init“的进程。在Linux System里面,所有的进程都是由init进程fork出来的,我们的zygote进程也不例外。

App:

● 一个单独的dalvik虚拟机
● 一个单独的进程

系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的
在这里插入图片描述

2.2、System_server

SystemServer也是一个进程,而且是由zygote进程fork出来的。知道了SystemServer的本质,这个进程是Android Framework里面两大非常重要的进程之-—另外一个进程就是上面的zygote进程。SystemServer非常重要,因为系统里面重要的服务都是在这个进程里面开启的,比如ActivityManagerService、PackageManagerService、WindowManagerService

2.3、ActivityManagerService

ActivityManagerService,简称AMS,服务端对象,负责系统中所有Activity的生命周期。ActivityManagerService进行初始化的时机很明确,就是在SystemServer进程开启的时候,就会初始化ActivityManagerService。

在这里插入图片描述
下面介绍下Android系统里面的服务器和客户端的概念。

App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信
在这里插入图片描述

2.4、Instrumentation和ActivityThread

每个Activity都持有Instrumentation对象的一个引用,但是整个进程只会存在一个Instrumentation对象。Instrumentation这个类里面的方法大多数和Application和Activity有关,这个类就是完成对Application和Activity初始化和生命周期的工具类。Instrumentation这个类很重要,对Activity生命周期方法的调用根本就离不开他,他可以说是一个大管家。

ActivityThread,依赖于UI线程。App和AMS是通过Binder传递信息的,那么ActivityThread就是专门与AMS的外交工作的。

2.5、ApplicationThread

在这里插入图片描述
而且由于继承了同样的公共接口类,ActivityManagerProxy提供了与ActivityManagerService一样的函数原型,使用户感觉不出Server是运行在本地还是远端,从而可以更加方便的调用这些重要的系统服务。

服务端–>客户端

还是通过Binder通信,不过是换了另外一对,换成了ApplicationThread和ApplicationThreadProxy。
在这里插入图片描述

他们也都实现了相同的接口IApplicationThread

 private class ApplicationThread extends ApplicationThreadNative {}
 public abstract class ApplicationThreadNative extends Binder implements IApplicationThread{}
 class ApplicationThreadProxy implements IApplicationThread {}

三、启动流程

3.1、创建进程

①先从Launcher的startActivity()方法,通过Binder通信,调用ActivityManagerService的startActivity方法。

②一系列折腾,最后调用startProcessLocked()方法来创建新的进程。

③该方法会通过前面讲到的socket通道传递参数给Zygote进程。Zygote孵化自身。调用ZygoteInit.main()方法来实例化ActivityThread对象并最终返回新进程的pid。

④调用ActivityThread.main()方法,ActivityThread随后依次调用Looper.prepareLoop()和Looper.loop()来开启消息循环。

方法调用流程图如下:
在这里插入图片描述
在这里插入图片描述

①App发起进程:当从桌面启动应用,则发起进程便是Launcher所在进程;当从某App内启动远程进程,则发送进程便是该App所在进程。发起进程先通过binder发送消息给system_server进程;

②system_server进程:调用Process.start()方法,通过socket向zygote进程发送创建新进程的请求;

③zygote进程:在执行ZygoteInit.main()后便进入runSelectLoop()循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程;

④新进程:执行handleChildProc方法,最后调用ActivityThread.main()方法。

3.2、绑定Application

上面创建进程后,执行ActivityThread.main()方法,随后调用attach()方法。

将进程和指定的Application绑定起来。这个是通过上节的ActivityThread对象中调用bindApplication()方法完成的。该方法发送一个BIND_APPLICATION的消息到消息队列中, 最终通过handleBindApplication()方法处理该消息. 然后调用makeApplication()方法来加载App的classes到内存中。

方法调用流程图如下:
在这里插入图片描述

3.3、显示Activity界面

经过前两个步骤之后, 系统已经拥有了该application的进程。 后面的调用顺序就是普通的从一个已经存在的进程中启动一个新进程的activity了。

实际调用方法是realStartActivity(), 它会调用application线程对象中的scheduleLaunchActivity()发送一个LAUNCH_ACTIVITY消息到消息队列中, 通过 handleLaunchActivity()来处理该消息。在 handleLaunchActivity()通过performLaunchActiivty()方法回调Activity的onCreate()方法和onStart()方法,然后通过handleResumeActivity()方法,回调Activity的onResume()方法,最终显示Activity界面。

生命周期管理
在这里插入图片描述

public void execute(ClientTransaction transaction) {
		//oncreate
        executeCallbacks(transaction);
		//其他生命周期
        executeLifecycleState(transaction);
}
 
 private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
		//oncreate
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }
		//执行其他生命周期
        // Execute the final transition with proper parameters.
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

四、Activity管理方式

在这里插入图片描述

4.1、Activity管理相关的数据结构包括:

  • ActivityRecord
  • TaskRecord
  • ActivityStack
  • ActivityDisplay
  • ActivityStackSupervisor
  • ProcessRecord

4.2、各类型数据详细介绍

4.2.1、ActivityRecord:Activity管理的最小单位,它对应着用户界面;

在这里插入图片描述

4.2.2、TaskRecord

每一个TaskRecord都可能存在一个或多个ActivityRecord,栈顶的ActivityRecord表示当前可见的界面;
在这里插入图片描述
TaskRecord的行为侧重在TaskRecord本身的管理:增/删/改/查任务栈中的元素。
在这里插入图片描述

4.2.3、ActivityStack

每一个ActivityStack都可能存在一个或多个TaskRecord,栈顶的TaskRecord表示当前可见的任务;
在这里插入图片描述
Activity状态的变迁,不仅仅是给ActivityRecord.state赋一个状态值那么简单,ActivityStack要对栈进行调整:之前的Activity要销毁或者挪到后台,待显示的Activity要挪到栈顶,这一调整,涉及到的工作就多了。
在这里插入图片描述

4.2.4、ActivityDisplay

Android支持多屏显示,在不同的显示设备上可以有不同的ActivityStack。

ActivityStack都是通过ActivityStackSupervisor管理起来的。 在ActivityStackSupervisor内部,设计了ActivityDisplay这个内部类,它对应到一个显示设备,默认的显示设备是手机屏幕。 ActivityStackSupervisor间接通过ActivityDisplay来维护多个ActivityStack的状态。

在这里插入图片描述

4.2.5、ActivityStackSupervisor

管理着多个ActivityStack,但当前只会有一个获取焦点(Focused)的ActivityStack;
在这里插入图片描述

  1. AMS初始化构造函数时会创建一个ActivityStackSupervisor对象。
  2. 一个ActivityRecord对应一个Activity,保存了一个Activity的所有信息;但是一个Activity可能会有多个ActivityRecord,因为Activity可以被多次启动,这个主要取决于其启动模式。
  3. 一个TaskRecord由一个或者多个ActivityRecord组成,这就是我们常说的任务栈,具有后进先出的特点。
  4. ActivityStack则是用来管理TaskRecord的,包含了多个TaskRecord。
  5. ActivityDisplay中有个mStack的ActivityStack的列表,管理着在该显示界面显示的所有ActivityStack
  6. adb shell dumpsys activity得到Activity的所有信息
    在这里插入图片描述

4.2.5、ProcessRecord

记录着属于一个进程的所有ActivityRecord,运行在不同TaskRecord中的ActivityRecord可能是属于同一个 ProcessRecord。

在这里插入图片描述

五、View显示流程

在这里插入图片描述
在这里插入图片描述

六、参考链接

Activity的启动流程简述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值