注:本文为作者学习笔记,如有误,请各位大佬指点
系统进程运行环境的初始化
-
Context是一个抽象类,它可以访问application环境的全局信息和各种资源信息和类
-
context功能:
- 对Activity、Service生命周期的管理
- 通过Intent发送广播/注册广播接收者
- 访问APK各种资源,比如Reservice、AssertManager等
- 访问Package的相关资源
- APK的权限管理
-
Android进程分为:
-
应用进程
ActivityThread就是应用进程的主线程,
应用进程启动后,首先会执行ActivityThread的main(),
应用程序也是通过ActivityThread来和AMS通信,调用和执行四大组件。
-
系统进程
SystemServer是Android的系统进程,
由于它也有Activity和一些系统资源,所以为了保证调用方式的统一,它也需要Activity和Context等运行环境,所以SystemServer也是一个特殊的应用程序。
-
-
系统Context的创建过程
在启动SystemServer启动之后,执行createSystemContext(),
在这个方法内部会完成系统进程运行环境的初始化,包括创建ActivityThread线程,ResourcesManager对象的创建和初始化,LoadedAPK的创建和初始化,LoadedAPK代表一个系统进程的APK,它里面存储资源的位置、JNI包的位置等,代表的就是Framework-res-apk,ContextImpl的构造方法创建一个Context,会将ResourcesManager、LoadedAPK加载进去,最终生成一个和系统进程相关的Context。
ActivityThread和Context就构成了Android程序的运行环境。
ActivityThread、ApplicationThread
ActivityThread
代表Android的主线程(不是线程类),系统创建完一个新的应用程序后,会在这个进程的主线程中调用ActivityThread的main(),里面会执行一个loop的循 环,使当前线程进入消息循环。
所以Android应用进程的入口函数是ActivityThread的main(),就是一个ActivityThread类对应一个应用程序进程。
ApplicationThread
是ActivityThread的内部类, 是一个Binder对象。在此处它是作为IApplicationThread对象 的server端,等待client端的请求,然后进行处理,最大的client就是AMS。
AMS是啥
-
AMS是什么
位于应用框架层,负责系统中四大组件的启动、切换、调度,及应用进程的管理和调度工作
-
什么时候初始化?
在SystemServer进程开启的时候,就会初始化AMS
-
简介
-
AMS通过使用一些系统资源和数据结构(如进程、任务栈、记录Activity生命周期的状态机等)来管理Activity生命周期。
-
当用户在设备上执行新的操作时,AMS会找到相应的任务栈,并根据其优先级来判断应该启动哪个Activity。
-
AMS也负责检查和处理系统内存的使用情况,并根据需要重新排列和重组任务栈中的Activity。
-
ActivityTaskManagerService(ATMS)是Android 10 新增的系统服务类,ATMS承担了AMS的部分工作(activities、task、stacks、display相关),比如将activity的启动相关的调用转移到ATMS了。
-
-
AMS功能
-
组件状态管理
包括四大组件的开启、关闭等(比如startActivity、startActivityAndWait、activityPaused、stopActivity、removeContentProvide)
-
组件状态查询
查询组件当前运行等情况(比如getCallingActivity、getService)
-
Task相关
包括removeTask、removeSubTask、moveTaskBackwards、moveTaskToFront等
-
AMS是通过ActivityStack及其他数据结构佬记录,管理系统中的activity及其他组件的状态,并提供查询功能的一个系统服务
-
AMS原理
-
应用程序启动过程
点击应用程序图标时,由Launcher应用程序向AMS发送一个启动请求。
AMS根据包名和类名找到对应的Activity,并启动activity。
AMS在启动activity过程中,会创建activity所在的进程,并控制生命周期。
-
Activity生命周期的管理
AMS通过与Zygote进行通信,创建Activity实例,
然后根据activity的状态来管理它的运行状态,
当应用程序处于后台时,AMS会将其进程变成缓存进程,
当内存不足时,AMS会杀死缓存进程。
AMS还负责监测应用程序的内存使用情况,内存不足,就会根据优先级来终止一些应用程序的Activity。
-
应用程序之间交互
当用户启动一个新应用程序时,AMS检查该应用程序是否已经在运行,根据需要执行操作:
如果已经在运行,就直接切换到这个应用程序;
如果不存在,就启动这个应用程序;
如果在后台运行,就把它切换到前台。
-
系统服务的调度
系统服务包括WI-FI、蓝牙等,AMS会启动、停止、重启这些服务,以保证系统正常运行。
-
应用程序的任务管理
将多个应用程序的activity组成一个任务,提供任务导航和管理等功能。
-
应用程序的权限管理
当应用程序请求权限时,AMS会弹出对话框询问用户是否授权,
如果用户授权,就将应用的权限信息存储到系统中。
常用类和方法
-
ActivityManagerService类
AMS的核心类,负责管理应用程序的生命周期、进程的创建和销毁
- startProcessLocked() 启动一个新进程
- killProcessesLocked() 杀死不必要的进程
- attachApplicationLocked() 将应用程序绑定到AMS
- handleAppDiedLocked() 处理应用程序死亡事件。
-
ActivityStack类
管理应用程序的Activity栈(activity任务),一个ActivityStack对应一个Activity任务。
- startActivityLocked() 启动一个新的Activity
- moveToBackLocked() 将当前Activity移动到栈底
-
ProcessRecord类
一个进程实例,负责管理进程的生命周期。进程之间通信采用Binder机制。
-
startProcess() 启动一个新的进程
-
kill() 结束进程
-
-
ActivityTaskManagerService类
处理应用程序的Task相关问题。Task是一组相关的Activity集合,他们可以共享一个Back键返回栈,通常处于一个任务栏中。
- startActivity(Intent intent) 启动指定的Activity,并添加到Task中
- moveTaskToFront(int taskId, int flags) 将指定的Task移动到前台
SystemServer加载AMS
Zygote进程会创建SystemServer进程,AMS是在SystemServer中启动的:
在run()里面新建一个SystemServiceManager对象,然后加到本地服务列表中,
接着启动三类服务:引导服务(AMS就是其中一个)、核心服务、其他服务:
- 创建AMS对象,并启动服务
- 将AMS所在的系统进程添加到进程管理中(完成AMS注册到SystemManager中)
- 为系统进程安装ContentProvider对象
- 在systemReady方法中做善后
然后启动AMS的主线程Looper,用于处理AMS的各种操作。
App启动中的AMS流程
- 用户点击应用程序图标,系统通过Launcher应用程序给AMS发送一个启动应用程序的请求。
- AMS接收到启动请求后,先检查应用程序是否已经运行,
- 如果已经运行,则直接把应用程序的任务栈置于前台,并把最上层的activity显示在屏幕上。
- 如果程序没有运行,ANS就会根据包名和activity类名创建一个新的进程,把它添加到系统的进程列表中。
- AMS会在新的进程中创建一个ActivityThread实例,并通过Binder机制与该进程进行通信。
- ActivityThread负责处理应用程序的生命周期和界面显示等任务。在创建完ActivityThread实例后,AMS会调用ActivityThread的main()启动该线程的主线程。
- 主线程启动后,ActivityThread会初始化应用程序的上下文环境,并加载应用程序的资源,然后ActivityThread会调用Instrumentation的callApplicationOnCreate(),通知应用程序的application实例进行初始化操作。
- 应用程序的application实例初始化完成后,ActivityThread会调用Instrumentation的newActivity()创建启动activity的实例,并将其添加到任务栈中。
- ActivityThread会调用activity的onCreate(),执行应用程序的初始化逻辑。在这个过程中,activity可以加载布局、注册监听器等。
- 当Activity的onCreate()执行完后,ActivityThread会调用activity的onStart(),使activity进入可见状态
- 最后,ActivityThread会调用activity的onResume(),使activity进入前台并显示在屏幕上。
通信方式
对于Android上层架构,最常用的通信方式是Binder、Socket、Handler,当然也有少量其他的IPC方式,比如杀进程Process.killProcess() 采用的是signal方式。
为何Android要采用Binder作为IPC机制
- 管道:在创建时分配一个page大小的内存,缓存区大小比较有限。
- 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;
- 共享内存:无须复制,共享缓冲区直接附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
- 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信;
- 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为 进程间以及同一进程内不同线程之间的同步手段。
- 信号: 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;
使用Binder的理由
见
Binder跨进程通信的优点