android 从点击图标到启动Activity的流程

一、前期准备

1.一些概念的介绍

ActivityManagerServices,简称AMS,服务端对象,负责系统中所有Activity的生命周期

ActivityThread,App的真正入口。当开启App之后,会调用main()开始运行,开启消息循环队列,这就是传说中的UI线程或者叫主线程。与ActivityManagerServices配合,一起完成Activity的管理工作

ApplicationThread,用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。

ApplicationThreadProxy,是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。

Instrumentation,每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。

ActivityStack,Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。

ActivityRecord,ActivityStack的管理对象,每个Activity在AMS对应一个ActivityRecord,来记录Activity的状态以及其他的管理信息。其实就是服务器端的Activity对象的映像。

TaskRecord,AMS抽象出来的一个“任务”的概念,是记录ActivityRecord的栈,一个“Task”包含若干个ActivityRecord。AMS用TaskRecord确保Activity启动和退出的顺序。如果你清楚Activity的4种launchMode,那么对这个概念应该不陌生。

2.android启动过程中的一些东西

1)zygote是什么?有什么作用?

zygote意为“受精卵“。Android是基于Linux系统的,而在Linux中,所有的进程都是由init进程直接或者是间接fork出来的,zy我们都知道,每一个App其实都是

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

所以当系统里面的第一个zygote进程运行之后,在这之后再开启App,就相当于开启一个新的进程。而为了实现资源共用和更快的启动速度,Android系统开启新进程的方式,是通过fork第一个zygote进程实现的。所以说,除了第一个zygote进程,其他应用所在的进程都是zygote的子进程,这下你明白为什么这个进程叫“受精卵”了吧?因为就像是一个受精卵一样,它能快速的分裂,并且产生遗传物质一样的细胞

2)SystemServer是什么?怎么启动的

SystemServer也是一个进程,而且是由zygote进程fork出来的。

系统里面重要的服务都是在这个进程里面开启的,比如ActivityManagerService、 PackageManagerService、WindowManagerService等等

具体启动过程:

  1. 在zygote开启的时候,会调用ZygoteInit.main()进行初始化,会调用startSystemServer()。
  2. startSystemServer()方法中会fork SystemServer。

3)ActivityManagerService的启动

  1. 在SystemServer进程开启的时候,就会初始化ActivityManagerService。
  2. 在startBootstrapServices()中完成初始化(这个方法还完成了许多系统重要服务的初始化)。
  3. 在这之前的createSystemContext()方法中已经完成了ActivityThread的创建

二、启动Activity的正式流程

第一步:launcher进程通知AMS自己想要启动一个应用的主activity,其中Launcher和AMS的通信使用了跨进程技术,流程图如下,其中ActivityManagerProxy是AMS的远程接口;

android 从点击图标到启动Activity的流程_第1张图片

  1. 首先我们需要了解到的就是Launcher本质上也是一个应用程序,和我们的App一样,也是继承自Activity。
  2. 而我们在桌面上的图标本质上是一个BubbleTextView对象,除了在桌面上有图标之外,在程序列表中点击图标,也可以开启对应的程序,这个图标是一个PagedViewIcon对象。
  3. 所以点击桌面图标实际调用的就是BubbleTextView的点击事件。而该电机事件实际调用的就是Launcher中的startActivitySafelf()方法,而startActivitySafely()方法,实际上是调用了StartActivity方法,所以我们现在明确了,Launcher中开启一个App,其实和我们在Activity中直接startActivity()基本一样,都是调用了Activity.startActivityForResult()。
  4. 而在startActivityForResult()方法中实际上还是调用了mInstrumentation.execStartActivity()这个方法,
  5. 所以当我们在程序中调用startActivity()的 时候,实际上调用的是Instrumentation的相关的方法(execStartActivity)。
  6. Instrumentation这个类很重要,对Activity生命周期方法的调用根本就离不开他,而具体怎么调用,那就要看ActivityThread的了(包括暂停,启动Activity等)。
  7. 而execStartActivity()这个方法中实际上又是调用了ActivityManagerNative.getDefault() .startActivity方法,而这里的ActivityManagerNative.getDefault返回的就ActivityManagerService的远程接口,即ActivityManagerProxy,而这里进行的就是IPC通信,利用Binder对象,调用transact(),把所有需要的参数封装成Parcel对象,向AMS发送数据进行通信。
  8. 到这里就完成了向AMS发出启动Activity的请求

 

第二步:AMS收到启动activity的请求后会调整一下自身的状态(为后面启动新的activity做准备)并要求Launcher当前栈顶的activity进入pause状态,流程图如下,其中ApplicationThreadProxy是ApplicationThread的远程接口;

android 从点击图标到启动Activity的流程_第2张图片

第三步:Launcher pause完当前栈顶activity后通知AMS可以开始启动新activity了,因为这是一个待启动进程的主activity,因此AMS要先启动一个新的进程然后才能在新的进程中完成启动主activity的任务,其中Process.start接口会加载一个ActivityThread类并调用其main方法启动一个新的进程,此时Launcher基本完成任务,后面主要是新进程和AMS的交互来完成activity的真正启动,流程图如下;

android 从点击图标到启动Activity的流程_第3张图片

第四步:新的进程启动后会通过调用attachApplication与AMS建立关联,AMS也会将该进程相关的一些信息保存起来以便于后期管理,准备就绪后AMS会通过ApplicationThread的远程接口ApplicationThreadProxy来调用scheduleLaunchActivity通知新进程开始真正启动activity的工作了,activity的onCreate和onResume函数都是在ActivityThread的handleLaunchActivity中完成的

 

android 从点击图标到启动Activity的流程_第4张图片

这篇文章是我在学习安卓activity启动过程中做的一些总结,文章内容和图片都是总结自

https://www.jianshu.com/p/6037f6fda285和https://blog.csdn.net/xgq330409675/article/details/78938926

这里自己就是做个小笔记,个人认为这样看着更方便些,我这里就没有贴源码了,想看源码的可以去那两篇博文中结合自己的实际情况去看 

你可能感兴趣的:(Android,开发)