Activity发动流程由于篇幅较长,将分述两篇文章进行解说。
上文首要进行概念提要和流程总述,下文首要从源码视点逐步探寻流程经过
一文搞定面试 | Activity发动流程之冷热发动(上)
一文搞定面试 | Activity发动流程之冷热发动(下)
概念提要
什么是冷\热发动
直观来说,区别冷\热发动的外在体现便是点击桌面使用图标时,打开APP所需的时刻长短
使用在发动过程中,需求依靠其所属进程和一些相关目标(如Application、Activity)。其间冷发动
是使用从无到有
的过程,需求创立新的进程和目标,耗时较长;而热发动
则是从有到有
,仅需求进行目标的状况恢复,因而耗时较短;期间还有另一种场景,部分目标被回收了,但进程仍然存活,则为暖发动
,耗时适中,这种场景可经过开发者选项-不保留活动
进行模拟
为什么发动使用需求新的进程
dalvik虚拟机
(DVM,与JVM有必定的联系,可是不完全相同,它们都能够履行Java字节码,可是DVM使用了不同的指令集和文件格局)是一种为Android使用提供运转环境的虚拟机,它是针对手机硬件资源有限而规划的。每个使用发动都运转一个独自的DVM,每个DVM独自占用一个Linux进程。这样能够保证使用之间的隔离和稳定性。
新进程是怎么创立的
Android开机从Linux内核发动视点能够如此描绘:
- 初始化CPU、内存、中断、时钟等硬件资源,并创立第一个用户进程
init
- init进程会解析init.rc文件,创立一些用户空间的看护进程和服务,其间第一个创立的Java进程是
Zygote进程
,也是所有Java进程的父进程 - Zygote进程会加载虚拟机、预加载类和资源,并注册
Zygote Socket
服务端套接字,等候AMS
恳求创立新的使用进程。Zygote进程还会fork
出System Server
进程,其间包括AMS、WMS、PMS等重要服务
以上透露了几个重要信息:
- System Server进程是由Zygote进程fork出来的,且包括AMS等服务
- 使用进程是由AMS向Zygote建议Socket通讯进行创立的
由此发生两个问题:
- 为什么进程都是fork出来的?
fork会仿制一些如仓库、地址空间、寄存器等资源到子进程,以完结资源共享,节省其重新分配和初始化的所需的时刻和内存,到达提效的目的
- 一般我们有了解Android的进程间通讯选用的是Binder,那AMS恳求fork时为何选用Socket?
三点原因:多线程问题、注册时刻问题、功能损耗
- Binder机制需求创立线程池,fork一个多线程的进程可能导致锁异常
- Binder机制源于ServiceManager,且需求注册服务。而Zygote进程是首个Java进程,Socket通讯只需求监听端口即可
- Binder机制虽然功率更高,但需求进行数据仿制和序列化等操作,而恳求fork进程时传递的数据较简略,不需求复杂的数据处理,所以这种场景下Socket机制可能更节省资源
进程间通讯与Binder
进程间的通讯是内核空间
和用户空间
的数据交换,copy_from_user和copy_to_user是有功能开销的,而挑选Binder,便是由于其使用了mmap
(不作打开)完结了数据在内核空间和用户空间的共享,避免了多次仿制。当然还有其他技术优化了全体的通讯功率,这里不作赘述
Binder是一种依据Client-Server形式的进程间通讯(IPC)机制
从图上我们能够了解到:
- 客户端建议恳求使用Proxy、服务端处理恳求使用Stub,(这个是别的总结的)而Service Manager是服务办理会集侧,服务端注册服务后得到Binder相关服务名,客户端依据服务名获取对应Binder从而转化为Proxy以调用
- 数据在传递过程中需求进行序列化和反序列化
- 在Server处理过程中,Client线程处于挂起状况。而Server在不处理时处于休眠状况
- mmap首要使用在数据包的仿制传递环节
在规划上,选用IBinder接口,上图中的流程笼统为transact()
和onTransact()
,然后依据官方API注释给出如下论述
这些办法答应你向一个IBinder目标发送一个调用,并接收一个传入到Binder目标的调用。
这个事务API是同步的,这意味着对{@link #transact transact()}的调用在目标从{@link Binder#onTransact Binder.onTransact()}回来之前不会回来;这是在调用本地进程中存在的目标时的预期行为,
底层的进程间通讯(IPC)机制保证了当跨进程时也具有相同的语义。
流程总述
后续关于发动流程均以冷发动为例,热发动包括其间,不作独自叙说,仅进行简略提点带过
已知,桌面Launcher是一个使用
先过冷发动新建使用进程的流程
- 首先,在桌面当点击使用图标时,会先判别使用对应进程是否存在,如果不存在的话,就需求创立新进程
- 而使用进程的办理在大名鼎鼎的AMS中,所属System Server进程,由ServerManager派生
- 而使用进程的发生,由Zygote进程进行fork,从AMS进行建议,选用Socket通讯
- 那Launcher作为一个使用,需求判别使用进程是否存在,自然应该经过Binder询问AMS,如果不存在,再由其恳求Zygote建议fork
那使用进程创立后需求做什么呢?
- 使用进程创立后,需求进行创立主线程,并绑定给AMS,然后开启looper
- 为什么要绑定给AMS,这个等下打开说说,由于AMS需求会集办理悉数使用的活动仓库和四大组件
- 绑定完结后,AMS则需求告诉Application进行startActivity,至此完结发动
AMS是怎么会集办理悉数使用的?
AMS是Android系统的核心服务之一,它负责四大组件(Activity、Service、BroadcastReceiver、ContentProvider)的
发动、调度和办理
,以及进程的创立、毁掉和优先级调整等工作。
这张图十分直观,来看看其间的几个要素:
- ActivityRecord:即对应一个Activity
- TaskRecord:了解Activity发动形式的,应该知道singleInstance会有独自的使命栈,包括
taskAffinity
的栈亲和设置,都会影响ActivityRecord归属的TaskRecord使命栈 - ActivityStack:则是保护一个使用内的TaskRecord,与TaskRecord结合完结了不同的发动形式和使命栈的切换,满足不同的需求和场景。也能够完结多窗口环境和多使命处理,进步用户体会和功率。
- ActivityStackSupervisor:则是AMS进行统一办理Activity仓库的大管家了,坐落top栈顶的ActivityStack,即为被focus的使用
- ProcessRecord:望文生义便是使用进程的包装,前面说到新的使用进程完结创立后需求attach绑定给AMS
一图看懂
经过对以上内容的了解和把握,再来结合看这张图,根本对Activity发动流程也就不这么望而生畏了
当然图中一些类并没有说到,由于在全体流程中是上下承接的责任分工效果,并非主体内容,将在一文搞定面试:Activity发动流程之冷热发动(下)中跟从源码逐步探寻和整理
图片取自 # Android Application 发动流程剖析及其源码调用探求
拜读
第一篇主攻源码流程,第二篇主攻概念及思路解析,两篇的阅读次序能够不必定,但结合起来,十分有助于了解
# Android使用发动流程
# Android使用发动流程剖析
# Android Application 发动流程剖析及其源码调用探求
如果觉得本文对你有帮助,无妨
点赞+保藏+重视
支撑一波,感谢肯定和青睐当然,更希望
初读点赞
、再读保藏
、三而重视