- 理解AMS的前提
- Android的体系结构
- 系统的启动流程
- 什么是Binder
- AIDL
- 准备知识学习好之后,从二个方面来学习AMS
- Activity的启动过程(其它组件的启动类似)—>体现AMS的作用
- 这一部分不做具体的源码分析(具体的源码分析之前有总结过笔记),只总结大体的流程
- Hook AMS—> 查看启动Activity会启动哪些AMS的方法
- Activity的启动过程(其它组件的启动类似)—>体现AMS的作用
一.Android的体系结构
- Android的体系结构
-
底层是基于Linux,第三成包含大量的库和android运行时,这两层通过系统调用进行调用;
-
做应用层一般熟悉1.2层即可,若想成为资深级的专家。可以看一下Linux相关的书籍(如:Linux内核设计与实现、深入理解Linux);主要看的是文件管理、进程管理、进程调度、系统调用、数据结构、终端管理、内存管理、io(如epoll,android底层的很多读写是用这个);
二.Android的启动过程
1.大体流程
- Android系统的启动流程是比较复杂的,这里只梳理大体流程;
- Android系统的启动流程主要有以下几步(先实现了解,后续有精力再去深入)
- 1.启动电源,加载引导程序BootLoader(理解成一个小程序,将系统os拉起来)到RAM,然后执行;
- 2.当内核启动后,会做一些初始化工作,并在系统文件中找到init.rc,并启动init进程;
- 3.init进程启动:初始化和启动属性服务,并且启动Zygote进程;
- 4.Zygote进程启动:创建Java虚拟机并为Java虚拟机注册JNI方法,创建服务器端Socket,启动SystemServer进程;
- 5.SystemServer进程启动:启动Binder线程池和SystemServiceManager,并且启动各种系统服务;
- 6.Launcher启动:被SystemServer进程启动的AMS会启动Launcher;
-
SysCall属于系统调用(关于这些概念,可以通过《操作系统的哲学》一书来学习,在这里明白用户空间,内核空间,系统调用即可);
-
引导服务中最终要的服务就是AMS,需要第一时间运行起来;
-
Zygote进程优先于SystemServer进程启动,通信方式有两种,接着换一个角度看一下App启动的大体流程;
- 既然应用程序启动activity需要AMS的调控,那么接下来我们就来看看activity的启动过程以及过程中,AMS如何对应用程序加以调度,并且和应用程序之间进行交互的。Activity的启动入口是startActivityForResult(),startActivity()其实也是调用了startActivityForResult(),那么就从这个入口去看看具体的启动流程吧;
三.什么是Binder
1.什么是Binder
2.Binder是如何启动的
- 这部分先了解即可
- Binder神图:深入理解了Binder之后,可以再看下图
3.Aidl
- 使用到了动态代理
- 共同实现业务接口
- 代理对象包含实际对象
stub继承binder,实现了定义的接口
proxy实现了定义的接口,持有一个remote(是stub实体)
4.Binder通信的原理
- 非常重要,必须要明白;另外,Android为什么要采用Binder作为IPC机制,也非常重要;
- 面试题
- 当bindService的时候,会调到远端服务的onBind中去,通过AMS最终是调用客户端中定义的ServiceConnection的onServiceConnected回调,在会调用会得到服务端的IBinder对象,通过asInterface方法将IBinder转换成定义的接口(此时,该接口的实体是Proxy类),接着通过该接口引用调用接口中定义的方法,就会指定proxy中的方法,调用transact方法(然后客户端线程挂起,等待服务端数据返回[关于挂起和继续执行底层都是binder去实现]继续运行),触发调用服务端onTransact方法;
- 关于bindService的细节补充,在android L之后,intent不能隐式调用,需要转成显示调用;
5.Android为什么要采用Binder作为IPC机制
- Android系统是基于Linux内核的,Linux已经提供了管道、消息队列、共享内存和Socket等 IPC 机制。那为什么Android还要提供Binder来实现IPC呢?主要是基于性能、稳定性和安全性几方面的原因。
5.1.性能
- Socket 作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信;
- 消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程;
- 共享内存虽然无需拷贝,但控制复杂,难以使用;
- Binder 只需要一次数据拷贝,性能上仅次于共享内存;
5.2.稳定性
- Binder 基于 C/S 架构,客户端(Client)有什么需求就丢给服务端(Server)去完成,架构清晰、职责明确又相互独立,自然稳定性更好。共享内存虽然无需拷贝,但是控制负责,难以使用。从稳定性的角度讲,Binder 机制是优于内存共享的;
5.3.安全性
- Android 作为一个开放性的平台,市场上有各类海量的应用供用户选择安装,因此安全性对于 Android 平台而言极其重要。作为用户当然不希望我们下载的 APP 偷偷读取我的通信录,上传我的隐私数据,后台偷跑流量、消耗手机电量。传统的 IPC 没有任何安全措施,完全依赖上层协议来确保。首先传统的 IPC 接收方无法获得对方可靠的进程用户ID/进程ID(UID/PID),从而无法鉴别对方身份。Android 为每个安装好的 APP 分配了自己的 UID,故而进程的 UID 是鉴别进程身份的重要标志。传统的 IPC 只能由用户在数据包中填入 UID/PID,但这样不可靠,容易被恶意程序利用。可靠的身份标识只有由 IPC 机制在内核中添加。其次传统的 IPC 访问接入点是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。同时 Binder 既支持实名 Binder,又支持匿名 Binder,安全性高。
5.4.总结
-
基于上述原因,Android 需要建立一套新的 IPC 机制来满足系统对稳定性、传输性能和安全性方面的要求,这就是 Binder。
-
最后用一张表格来总结下 Binder 的优势:
6.系统使用服务大致流程分析
- ServiceManager是先启动的,其它服务会先注册到ServiceManager中,服务端需要使用服务的时候,通过ServiceManager拿到服务(代理),客户端就可以使用该服务;
7.Binder–AIDL通信细节
- 这部分的细节,我们暂时不去深究,但大概的流程需要有所了解。
四.应用进程的启动
1.相关的类
- 系统中的所有应用进程都是由Zygote进程fork出来的;
- SystemServer进程是系统进程,很多系统服务,例如ActivityManagerService、PackageManagerService、WindowManagerService…都是存在该进程被创建后启动;
- ActivityManagerServices(AMS):是一个服务端对象,负责所有的Activity的生命周期,AMS通过Binder与Activity通信,而AMS与Zygote之间是通过Socket通信;
- ActivityThread主角,UI线程/主线程,它的main()方法是APP的真正入口;
- ApplicationThread:一个实现了IBinder接口的ActivityThread内部类,用于ActivityThread和AMS的所在进程间通信;
- Instrumentation:可以理解为ActivityThread的一个工具类,在ActivityThread中初始化,一个进程只存在一个Instrumentation对象,在每个Activity初始化时,会通过Activity的Attach方法,将该引用传递Activity。Activity所有生命周期的方法都有该类来执行;
- 关于AMS源码部分,这里就略过,之前总结的App启动和Activity的启动流程分析的过程中都涉及有AMS,建议先看,然后再下方内容。以下,分别对每个步骤的流程进行一个大体的梳理,不同版本在细节上会存在差异。
2.点击应用图标(所干的事情)
- Lanucher进程跟AMS通信(Binder),告诉AMS需要启动的目标app;
- AMS创建进程(并非自己创建):通过socket通信通知Zygote去fork(涉及到Linux进程的创建过程知识)一个进程;
- 应用进程创建好之后,应用进程跟AMS是通过Binder进行通信;
3.根Activity启动过程涉及的进程之间的关系
- 换个角度看Lanuncher的启动
4.应用程序进程启动过程分析-时序图
5.AMS请求Zygote过程分析
6.Zygote进程fork进程分析
7.应用程序创建后细节一
8.应用进程Crash处理
9.Launcher请求AMS启动Activity
10.AMS到ApplicationThread的调用过程
11.ActivityThread启动Activity
12.IActivity接口分析
13.IApplicationThead接口分析
14.Activity通信模型
15.AMS家族介绍
16.AMS Android O–AIDL模型
17.Android P利用状态模式重构了部分代码
- 重构之后,阅读代码的难度有所增加(状态模式封装了请求)
五.Hook技术
- 插件化、微信分身
- hook没有注册的activity的启动
评论区