以Android 8.0版本为基础,以启动运行在新进程的Service为场景,分析启动的流程,了解了Binder和AMS后会好理解些。
Android-28版本有关AMS回调Activity生命周期的流程
从Android-28开始,AMS向客户端进程有关Activity部分的通信封装成一个统一的事务来操作,不再直接使用客户端进程ApplicationThread的本地代理了。
启动Activity过程
以Android 8.0版本为基础,以Launcher点击图标启动一个App来分析比较,这个过程需要很多次IPC,Launcher和AMS、AMS和App。
从IPC角度分析,启动流程大致为:
- Launcher与AMS进行IPC,通知AMS启动App;
- AMS做启动Activity之前的准备工作,Intent信息、LauncherMode、ActivityStack等完成后,AMS与Launcher进行IPC,通知Launcher进入后台;
- AMS检测目标Activity所在App进程是否存在,通知Zygote进程fork新进程;
- 新进程入口处
ActivityThread.main()
; - AMS通知App创建Application;
- AMS通知App创建Activity并回调相关生命周期
Activity中的mToken
什么是Token?
Token是ActivityRecord静态内部类,继承于IApplicationToken.Stub,是AMS为了客户端新启动的Activity所创建,字面上理解它是具有代表Activity令牌的一个Binder。
这个Binder是AMS为Activity创建的一个唯一标识,AMS进程管理App进程的Activity的生命周期,所以用可以跨进程的Binder来标识Activity最合适不过。
Token创建?
AMS在创建启动Activity之前创建了ActivityRecord,ActivityRecord包含了待创建Activity所有的信息,并在构造函数中创建了Token,最终Activity创建好之后会得到它在客户端的本地Binder代理。
浅析ServiceManager
通常客户端四大组件的交互少不了和AMS、PMS等系统服务的通信,客户端拿到AMS的远程Binder引用转换成客户端能够使用的代理,然后就可以和AMS通信了,但是这个远程Binder引用是怎么来的?
Activity启动模式
Android中Activity是直接和用户接触的组件,通常理解为页面组件,Androud默认有一个管理Activity的栈,每启动一个Activity都会将这个Activity实例压入栈中,按返回键便会把这个实例从栈中移除,如果栈中最后一个Activity实例被移除则应用退出。通常为了达到灵活的控制效果,Android可以在AndroidManifest.xml配置不同的模式来处理待启动Activity实例和栈的关系,如多个栈以及重复启动Activiy的相应规则等。
AndroidManifest.xml可以配置4种模式standard、singleTop、singleTask、singleInstance,也可以在Intent中调用Intent.setFlags(int flags)方法动态设置启动模式,并且代码设置的模式优先级高于在AndroidManifest.xml配置的4种模式。
Binder简单归纳总结
我对Binder的理解是:解决Android平台IPC的一种方案。它的优点是传输性能较好、相对稳定、架构清晰、安全性好、使用简单。
要理解Binder,从它的架构方面入手比较轻松一点。