Activity发动流程由于篇幅较长,将分述两篇文章进行解说。

上文首要进行概念提要和流程总述,下文首要从源码视点逐步探寻流程经过

一文搞定面试 | Activity发动流程之冷热发动(上)

一文搞定面试 | Activity发动流程之冷热发动(下)

概念提要

什么是冷\热发动

直观来说,区别冷\热发动的外在体现便是点击桌面使用图标时,打开APP所需的时刻长短

使用在发动过程中,需求依靠其所属进程和一些相关目标(如Application、Activity)。其间冷发动是使用从无到有的过程,需求创立新的进程和目标,耗时较长;而热发动则是从有到有,仅需求进行目标的状况恢复,因而耗时较短;期间还有另一种场景,部分目标被回收了,但进程仍然存活,则为暖发动,耗时适中,这种场景可经过开发者选项-不保留活动进行模拟

为什么发动使用需求新的进程

dalvik虚拟机(DVM,与JVM有必定的联系,可是不完全相同,它们都能够履行Java字节码,可是DVM使用了不同的指令集和文件格局)是一种为Android使用提供运转环境的虚拟机,它是针对手机硬件资源有限而规划的。每个使用发动都运转一个独自的DVM,每个DVM独自占用一个Linux进程。这样能够保证使用之间的隔离和稳定性。

新进程是怎么创立的

Android开机从Linux内核发动视点能够如此描绘:

  1. 初始化CPU、内存、中断、时钟等硬件资源,并创立第一个用户进程init
  2. init进程会解析init.rc文件,创立一些用户空间的看护进程和服务,其间第一个创立的Java进程是Zygote进程也是所有Java进程的父进程
  3. Zygote进程会加载虚拟机、预加载类和资源,并注册Zygote Socket服务端套接字,等候AMS恳求创立新的使用进程。Zygote进程还会forkSystem Server进程,其间包括AMS、WMS、PMS等重要服务

以上透露了几个重要信息:

  1. System Server进程是由Zygote进程fork出来的,且包括AMS等服务
  2. 使用进程是由AMS向Zygote建议Socket通讯进行创立的

由此发生两个问题:

  1. 为什么进程都是fork出来的?

fork会仿制一些如仓库、地址空间、寄存器等资源到子进程,以完结资源共享,节省其重新分配和初始化的所需的时刻和内存,到达提效的目的

  1. 一般我们有了解Android的进程间通讯选用的是Binder,那AMS恳求fork时为何选用Socket?

三点原因:多线程问题、注册时刻问题、功能损耗

  1. Binder机制需求创立线程池,fork一个多线程的进程可能导致锁异常
  2. Binder机制源于ServiceManager,且需求注册服务。而Zygote进程是首个Java进程,Socket通讯只需求监听端口即可
  3. Binder机制虽然功率更高,但需求进行数据仿制和序列化等操作,而恳求fork进程时传递的数据较简略,不需求复杂的数据处理,所以这种场景下Socket机制可能更节省资源

进程间通讯与Binder

进程间的通讯是内核空间用户空间的数据交换,copy_from_user和copy_to_user是有功能开销的,而挑选Binder,便是由于其使用了mmap(不作打开)完结了数据在内核空间和用户空间的共享,避免了多次仿制。当然还有其他技术优化了全体的通讯功率,这里不作赘述

Binder是一种依据Client-Server形式的进程间通讯(IPC)机制

一文搞定面试 | Activity启动流程之冷热启动(上)

从图上我们能够了解到:

  1. 客户端建议恳求使用Proxy、服务端处理恳求使用Stub,(这个是别的总结的)而Service Manager是服务办理会集侧,服务端注册服务后得到Binder相关服务名,客户端依据服务名获取对应Binder从而转化为Proxy以调用
  2. 数据在传递过程中需求进行序列化和反序列化
  3. 在Server处理过程中,Client线程处于挂起状况。而Server在不处理时处于休眠状况
  4. mmap首要使用在数据包的仿制传递环节

在规划上,选用IBinder接口,上图中的流程笼统为transact()onTransact(),然后依据官方API注释给出如下论述

这些办法答应你向一个IBinder目标发送一个调用,并接收一个传入到Binder目标的调用。

这个事务API是同步的,这意味着对{@link #transact transact()}的调用在目标从{@link Binder#onTransact Binder.onTransact()}回来之前不会回来;这是在调用本地进程中存在的目标时的预期行为,

底层的进程间通讯(IPC)机制保证了当跨进程时也具有相同的语义。

流程总述

后续关于发动流程均以冷发动为例,热发动包括其间,不作独自叙说,仅进行简略提点带过

已知,桌面Launcher是一个使用

先过冷发动新建使用进程的流程

  1. 首先,在桌面当点击使用图标时,会先判别使用对应进程是否存在,如果不存在的话,就需求创立新进程
  2. 而使用进程的办理在大名鼎鼎的AMS中,所属System Server进程,由ServerManager派生
  3. 而使用进程的发生,由Zygote进程进行fork,从AMS进行建议,选用Socket通讯
  4. 那Launcher作为一个使用,需求判别使用进程是否存在,自然应该经过Binder询问AMS,如果不存在,再由其恳求Zygote建议fork

那使用进程创立后需求做什么呢?

  1. 使用进程创立后,需求进行创立主线程,并绑定给AMS,然后开启looper
  2. 为什么要绑定给AMS,这个等下打开说说,由于AMS需求会集办理悉数使用的活动仓库四大组件
  3. 绑定完结后,AMS则需求告诉Application进行startActivity,至此完结发动

AMS是怎么会集办理悉数使用的?

AMS是Android系统的核心服务之一,它负责四大组件(Activity、Service、BroadcastReceiver、ContentProvider)的发动、调度和办理,以及进程的创立、毁掉和优先级调整等工作。

这张图十分直观,来看看其间的几个要素:

  1. ActivityRecord:即对应一个Activity
  2. TaskRecord:了解Activity发动形式的,应该知道singleInstance会有独自的使命栈,包括taskAffinity的栈亲和设置,都会影响ActivityRecord归属的TaskRecord使命栈
  3. ActivityStack:则是保护一个使用内的TaskRecord,与TaskRecord结合完结了不同的发动形式和使命栈的切换,满足不同的需求和场景。也能够完结多窗口环境和多使命处理,进步用户体会和功率。
  4. ActivityStackSupervisor:则是AMS进行统一办理Activity仓库的大管家了,坐落top栈顶的ActivityStack,即为被focus的使用
  5. ProcessRecord:望文生义便是使用进程的包装,前面说到新的使用进程完结创立后需求attach绑定给AMS

一文搞定面试 | Activity启动流程之冷热启动(上)

一图看懂

经过对以上内容的了解和把握,再来结合看这张图,根本对Activity发动流程也就不这么望而生畏了

当然图中一些类并没有说到,由于在全体流程中是上下承接的责任分工效果,并非主体内容,将在一文搞定面试:Activity发动流程之冷热发动(下)中跟从源码逐步探寻和整理

一文搞定面试 | Activity启动流程之冷热启动(上)

图片取自 # Android Application 发动流程剖析及其源码调用探求

拜读

第一篇主攻源码流程,第二篇主攻概念及思路解析,两篇的阅读次序能够不必定,但结合起来,十分有助于了解

# Android使用发动流程

# Android使用发动流程剖析

# Android Application 发动流程剖析及其源码调用探求

如果觉得本文对你有帮助,无妨 点赞+保藏+重视 支撑一波,感谢肯定和青睐

当然,更希望初读点赞再读保藏三而重视