ActivityManagerService的启动流程
介绍
这篇文章是讲,从手机桌面(Launcher)点击一个未启动app的图标到这个app启动完成的流程(冷启动)。android
整体流程
Launcher、AMS、Zygote、app都处于不一样的进程,他们之间须要跨进程才能通讯。
数据库
用户点击Launcher的app图标后,Launcher通知AMS,若是目标app未启动(冷启动),AMS会经过Socket来通知Zygote去建立进程,Zygote就fork出咱们要启动的app进程。
紧接着app要打开HomeActivity,须要与AMS交互
windows
- app -> AMS : 由于AMS启动时,就注册到ServiceManager了,因此app调用getService就能从ServiceManager获取到AMS的代理类IActivityManager(客户端)。app从而经过IActivityManager调用AMS(服务端)的方法。
- AMS -> app : AMS准备一个IBinder,叫IApplicationThread(服务端)。当app进程启动完成后,会调用IApplicationThread的attachApplication方法,把app的代理类ApplicationThread(客户端)做为参数传给AMS。AMS能够调用ApplicationThread的方法从而控制app。
IApplicationThread的实现类是ActivityThread的内部类ApplicationThread数据结构
看完流程图,咱们再来看时序图
图中的4就是attachApplication的过程,把app的代理类ApplicationThread交给AMS。
图中的5就是AMS作完一些处理后,经过app的代理类ApplicationThread来启动app的HomeActivity。
app
涉及的数据结构
在看源码以前,须要先了解几个重要的数据结构异步
ProcessRecord(进程)
第一类数据:描述身份的数据ide
- ApplicationInfo info:AndroidManifest.xml中定义的Application信息
- boolean isolated:是否是isolated进程
- int uid:进程uid
- int userId:这个是android作的多用户系统id,就像windows能够登陆不少用户同样,android也但愿能够实现相似的多用户
- String processName:进程名字,默认状况下是包名
- UidRecord uidRecord:记录已经使用的uid
- IApplicationThread thread:这个很重要,它是ApplicationThread的客户端,AMS就是经过这个对象给apk进程发送异步消息的(管理四大组件的消息),因此只有这个对象不为空的状况下,才表明apk进程可使用了
- int pid:进程的pid
- String procStatFile:proc目录下每个进程都有一个以pid命名的目录文件,这个目录下记载着进程的详细信息,这个目录及目录下的文件是内核建立的, proc是内核文件系统,proc就是process的缩写,涉及的目的就是导出进程内核信息
- int[] gids:gid组
- CompatibilityInfo compat : 兼容性信息
- String requiredAbi : abi信息
- String instructionSet : 指令集信息
第二类数据:描述进程中组件的数据ui
- pkgList:进程中运行的包
- ArraySet pkgDeps:进程运行依赖的包
- ArrayList activities:进程启动的全部的activity组件记录表
- ArraySet services:进程启动的全部的service组件记录表
- ArraySet executingServices:正在运行(executing)是怎么定义的?首先须要明确的是系统是怎么控制组件的?发送消息给apk进程,apk进程处理消息,上报消息完成,这被定义为一个完整的执行过程,所以正在执行(executing)被定义为发送消息到上报完成这段时间
- ArraySet connections:绑定service的客户端记录表
- ArraySet receivers:广播接收器的记录表
- ContentProviderRecord pubProviders:pub是publish(发布)的意思,ContentProvider须要安装而后把本身发布到系统(AMS)中后,才能使用,安装指的是apk进程加载ContentProvider子类、初始化建立数据库等过程,发布是将ContentProvider的binder客户端注册到AMS中
- ArrayList conProviders:使用ContentProvider的客户端记录表
- BroadcastRecord curReceiver:当前进程正在执行的广播 在本节中以上组件信息只是作一个简单的描述,之后单独分析组件管理的时候在详细介绍
此外还有描述进程状态的数据、和pss相关的数据、和时间相关的数据、crash和anr相关的数据、和instrumentation相关的数据、电源信息和调试信息等,spa
ActivityRecord
Activity在AMS内部是以ActivityRecord的形式存在的,Activity和ActivityRecord是一一对应的。线程
- ProcessRecord app:跑在哪一个进程
- TaskRecord task :跑在哪一个task
- ActivityInfo info :Activity信息
- int mActivityType:Activity类型
- ActivityState state:Activity状态
- ApplicationInfo appInfo :跑在哪一个app
- ComponentName realActivity :组件名
- String packageName :包名
- String processName :进程名
- int launchMode:启动模式
- int userId :该Activity运行在哪一个用户id
mActivityType
- APPLICATION_ACTIVITY_TYPE:普通应用类型
- HOME_ACTIVITY_TYPE:桌面类型
- RECENTS_ACTIVITY_TYPE:最近任务类型
ActivityState
- INITIALIZING
- RESUMED:已恢复
- PAUSING
- PAUSED:已暂停
- STOPPING
- STOPPED:已中止
- FINISHING
- DESTROYING
- DESTROYED:已销毁
ActivityRecord是在ActivityStarter的startActivity方法里建立的
TaskRecord
任务栈TaskRecord,内部维护一个 ArrayList 用来保存ActivityRecord。
- ActivityStack stack:当前所属的stack
- ArrayList mActivities:当前task的全部Activity列表
- int taskId
- String affinity:是指root activity的affinity,即该Task中第一个Activity
- int mCallingUid
- String mCallingPackage:调用者的包名
TaskRecord是在ActivityStarter的setTaskFromReuseOrCreateNewTask里建立的。
ActivityStack
ActivityStack,内部维护了一个 ArrayList ,用来管理TaskRecord。
手机有三个虚拟按键,按最右边的正方形按键,会显示最近任务,这个最近任务就是一个ActivityStack,桌面应用也是一个ActivityStack。
ArrayList mTaskHistory //保存全部的Task列表
ArrayList mStacks; //全部stack列表
final int mStackId;
int mDisplayId;
ActivityRecord mPausingActivity //正在pause
ActivityRecord mLastPausedActivity
ActivityRecord mResumedActivity //已经resumed
ActivityRecord mLastStartedActivity
全部前台stack的mResumedActivity的state == RESUMED, 则表示allResumedActivitiesComplete, 此时mLastFocusedStack = mFocusedStack;
ActivityStackSupervisor
ActivityStackSupervisor,顾名思义,就是用来管理ActivityStack的
- ActivityStack mHomeStack:桌面的stack
- ActivityStack mFocusedStack:当前聚焦stack
- ActivityStack mLastFocusedStack:正在切换
- SparseArray mActivityDisplays:displayId为key
- SparseArray mActivityContainers: mStackId为key
- home的栈ID等于0,即HOME_STACK_ID = 0;
ActivityStackSupervisor内部有两个不一样的ActivityStack对象:mHomeStack、mFocusedStack,用来管理不一样的任务。
ActivityStackSupervisor内部包含了建立ActivityStack对象的方法。
AMS初始化时会建立一个ActivityStackSupervisor对象
详细的流程
- Instrumentation:管理Activity的生命周期以及启动
- ActivityManagerProxy:AMS的代理对象
- ApplicationThreadProxy:启动APP的代理对象
- ApplicationThread是一个Binder服务,不是主线程
第9步是经过Handler来跨线程通讯,从子线程ApplicationThread走到主线程ActivityThread。