五大状态
- Starting
- Running
- Stopped
- Paused
- Destroyed
借用一张已经包浆的图
PS:Running和Paused是可视阶段,其余都是不可视
几大函数
- onCreate:通过setContentLayout初始化布局
- onStart:此时activity可见,但没有获得焦点,无法交互,正做动画的初始化
- onResume:获得焦点,可交互
- onPause:如弹窗,有activity覆盖当前activity,失去焦点,但可见
- onStop:activity不可见,系统内存紧张时会回收
- onDestroy:结束activity
进程优先级
前台进程>可见进程>service进程>后台进程>空进程
前台进程
用户当前在做的事所必须的进程,符合其一则为
- 进程的activity正在与用户进行交互
- 进程持有一个service,且此service与正在交互的activity绑定/通过startForeground()在前台运行/正在进行其生命周期回调函数
- 进程持有一个正在进行onReceive()的BroadcostReceiver
可见进程
不持有任何前台组件,但仍可见
- 进程持有activity,此activity不在前台,处于onPause
- 进程持有的service与可见的activtiy进行绑定
服务进程
没有和用户可见的组件绑定,所做的事情也是用户关心的,如后台下载、播放音乐的,除非内存不足,不然不会取消
当进程运行着一个startService开启的的service,且不属于前台和可见进程
后台进程
持有不可见activity,onStop调用,但没有调用onDestroy,系统会为了前三种进程任意杀死后台进程
空进程
不包含任何活跃的应用组件,则被认为是空进程
没有任何运行数据且还在内存空间,容易被杀死
启动流程
此处针对Activity A通过button点击启动位于不同进程的Activity B进行分析
概念梳理
- init进程:init是所有linux程序的起点,是Zygote的父进程。解析init.rc孵化出Zygote进程。Android是基于linux系统的,手机开机之后,linux内核进行加载。加载完成之后会启动init进程。init进程会启动ServiceManager,孵化一些守护进程,并解析init.rc孵化Zygote进程
- Zygote进程:Zygote是所有Java进程的父进程,所有的App进程都是由Zygote进程fork生成的。所有的App进程都是由Zygote进程fork生成的,包括SystemServer进程。Zygote初始化后,会注册一个等待接受消息的socket,OS层会采用socket进行IPC通信。每个应用程序都是运行在各自的Dalvik虚拟机中,应用程序每次运行都要重新初始化和启动虚拟机,这个过程会耗费很长时间。Zygote会把已经运行的虚拟机的代码和内存信息共享,起到一个预加载资源和类的作用,从而缩短启动时间。
- SystemServer进程:System Server是Zygote孵化的第一个进程。SystemServer负责启动和管理整个Java framework,包含AMS,PMS等服务。
- Launcher:Zygote进程孵化的第一个App进程是Launcher。
- 进程:Android系统为每个APP分配至少一个进程
- IPC:跨进程通信,Android中采用Binder机制。
- ActivityStack:Activity在AMS的栈管理,用来记录已经启动的Activity的先后关系,状态信息等。通过ActivityStack决定是否需要启动新的进程。
- ActivitySupervisor:管理 activity 任务栈
- ActivityThread:ActivityThread 运行在UI线程(主线程),App的真正入口。
- ApplicationThread:用来实现AMS和ActivityThread之间的交互。
- ApplicationThreadProxy:ApplicationThread 在服务端的代理。AMS就是通过该代理ActivityThread进行通信的。
- IActivityManager:继承与IInterface接口,抽象出跨进程通信需要实现的功能
- AMN:运行在server端(SystemServer进程)。实现了Binder类,具体功能由子类AMS实现。
- AMS:AMN的子类,负责管理四大组件和进程,包括生命周期和状态切换。AMS因为要和ui交互,所以极其复杂,涉及window。
- AMP:AMS的client端代理(app进程)。了解Binder知识可以比较容易理解server端的stub和client端的proxy。AMP和AMS通过Binder通信。
- Instrumentation:仪表盘,负责调用Activity和Application生命周期,负责监控系统与应用之间的交互。测试用到这个类比较多。
- ActivityStackSupervisor负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。
- mHomeStack管理的是Launcher相关的Activity栈
- mFocusedStack管理的是当前显示在前台Activity的Activity栈
- mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈
省流四步
- A告诉AMS准备启动B
- AMS处理请求,通知A进行Pause,A处理完后,通知AMS 自己已经完成Pause了
- B的进程还没启动,AMS首先启动一个新的进程,新进程启动完后通知AMS服务进程启动完毕
- AMS通知新进程启动B,B启动完毕后通知AMS服务启动完毕
AMS和应用进程间通信涉及进程间通信,与Binder有关
当创建了一个新的应用进程后,系统首先会启动ActivityThread,ActivityThread是应用进程的主线程,ActivityThread创建时会创建一个ApplicationThread对象,ApplicationThread实现了一个Binder服务端
新进程创建完时会通知AMS,同时会将ApplicationThread的代理端交付,因此AMS保存了所有应用进程的ApplicationThread的代理对象,用于给应用进程发送消息
Activity.startActivity
此处button点击函调用了该函数
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
//intent描述B,-1表示不返回结果
startActivityForResult(intent, -1, options);
……
}
Activity. startActivityForResult
public void startActivityForResult( String who, Intent intent, int requestCode, @Nullable Bundle options) {
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,intent, requestCode, options);
……
}
应用程序和系统间的交互都集中交给Instrumentation来做,便于监视活动
mMainThread.getApplicationThread()是前面提到的Binder对象,实现了Binder服务端,AMS保留其client用于通信
mToken则是binder代理对象,指向AMS中保存的一个ActivityRecord信息,mToken代表了A,AMS依据其得到A的信息
Instrumentation. execStartActivity
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
ApplicationThread whoThread = (IApplicationThread) contextThread;
try {
//intent做进程间传输的准备工作
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//进程间传输,终于调用到AMS服务中
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
}
……
}
通过ActivityManagerNative.getDefault().startActivity()调用AMS的startActivity方法
至此都是在A的进程完成的,需要进入SystemServer中
这里调用了startActivity来启动Activity(最常用的函数),里面调用startActivityForResult,但给出的请求码是-1,即不返回数据
startActivityForResult调用了Instrumentation的execStartActivity,并传入ApplicationThread给AMS作为通信的binder对象,也传入mToken作为指向A的ActivityRecord给AMS
AMS.startActivity
public final int startActivity (IApplicationThread caller, String callingPackage,Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,UserHandle.getCallingUserId());
}
caller就是App1进程的ApplicationThread的binder对象,
IBinder就是指向Activity A的ActivityRecord的Binder对象,前面提到的通信和获取活动信息所需
紧接着这种方法就调用了startActivityAsUser方法
AMS. startActivityAsUser
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,Intent intent,String resolvedType, IBinder resultTo, String resultWho,
int requestCode,int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
……
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
调用了activityStackSupervisor的startActivityMayWait方法
ActivityStackSupervisor是Activity调度的核心类
Activity的调度相关的工作都是在ActivityStackSuperVisor中处理
主要管理Task和Stack.它是在AMS启动的时候创建的。
startActivityMayWait
final int startActivityMayWait(IApplicationThread caller, int callingUid,String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
……
//PMS服务依据intent查询要启动的Activity B的信息,保存到ActivityInfo中
intent = new Intent(intent);
ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
//决定当前活动的stack
ActivityContainer container = (ActivityContainer)iContainer;
final ActivityStack stack;
if (container == null || container.mStack.isOnHomeDisplay()) {
stack = mFocusedStack;
} else {
stack = container.mStack;
}
……
//将PMS中查询到的Activity B的信息当做參数
int res = startActivityLocked(caller, intent, resolvedType, aInfo,voiceSession, voiceInteractor, resultTo, resultWho,requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,componentSpecified, null, container, inTask);
……
}
resolveActivity调用PMS服务依据Intent信息查询B的具体信息
查询是否有对应的ActivityStack,若传递过来的container为空,则指定Stack为当前获得焦点的ActivityStack,即mFocusedStack
ActivityStack分为几种
- Home Stack 为 Launcher所在的Stack,一些系统界面也在此Stack执行,SystemUI等
- FullScreen Stack 全屏的Activity所在的Stack,最常用
- Freeform模式的Activity所在Stack,即可以自由缩放,自由移动
- Docked Stack,分屏模式
- Pinned Stack 画中画
startActivityLocked
final int startActivityLocked(IApplicationThread caller,Intent intent, String resolvedType, ActivityInfo aInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,IBinder resultTo, String resultWho, int requestCode,int callingPid, int callingUid, String callingPackage,int realCallingPid, int realCallingUid, int startFlags,