文章参考:添加链接描述
文章参考:添加链接描述
五大状态
- 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, Bundle options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,ActivityContainer container, TaskRecord inTask) {
//callerApp 代表调用方的应用进程。即App1的应用进程
ProcessRecord callerApp = null;
if (caller != null) {
//依据caller找到AMS中保存的App1的processRecord对象
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
//得到App1应用进程的pid和应用的uid
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
}
……
}
……
//即调用者的Activity组件
ActivityRecord sourceRecord = null;
//返回结果的Activity组件
ActivityRecord resultRecord = null;
if (resultTo != null) {
//依据resultTo Binder对象得到其指向的ActivityRecord,即Activity A的ActivityRecord信息
sourceRecord = isInAnyStackLocked(resultTo);
//普通情况下请求的Activity和要接收返回结果的Activity是同一个
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
final int launchFlags = intent.getFlags();
……
//依据准备的信息,创建一个即将启动的ActivityRecord对象。即Activity B
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, this, container, options);
……
//将刚创建的目标Activity的ActivityRecord作为參数,继续调用startActivityUncheckedLocked方法来启动
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
……
return err;
}
依据传入的A的binder对象caller获得A的ActivityRecord信息,获取调用程序的pid和uid
加上ainfo创建一个ActivityRecord对象r,代表B
至此sourceRecord获取了A的组件消息,r获取了B的信息
最终调用startActivityUncheckedLocked启动B
startActivityUncheckedLocked
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
//依据flag获取对应的启动模式。我们代码中没有设置启动模式,所以默认应该是标准模式。这三个变量都应该是false
final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;
……
//即将要启动activity的 task
ActivityStack targetStack;
……
//是否新建一个Task
boolean newTask = false;
……
//获取Activity A的Task,然后赋值给B,即两个Activity位于同一个Task中
else if (sourceRecord != null) {
//获取Activity A所在的Task
final TaskRecord sourceTask = sourceRecord.task;
//将A所在的ActivityStack作为B启动的Stack
targetStack = sourceTask.stack;
targetStack.moveToFront("sourceStackToFront");
//获取ActivityStack中的 top Task是不是和当前的Task一致,假设不一致则将当前的Task移动到ActivityStack的顶端
final TaskRecord topTask = targetStack.topTask();
if (topTask != sourceTask) {
targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,r.appTimeTracker, "sourceTaskToFront");
}
……
//将当前Activity Stack mLastPausedActivity设置为null
targetStack.mLastPausedActivity = null;
//调用startActivityLocked方法
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
}
这里处理了Activity四种启动模式,根据Intent中的flag标志来决定不同的启动模式和Activity在Task中的位置
此处的启动模式是默认的,因此A和B同放在一个Task里面
每个Activity都位于一个Task中,一个Task能够包括多个Activity,同一个Activity也可由多个实例
Task管理在于近期任务列表和Back栈,AMS和WMS内部有一个容器Stack,android多窗体管理建立在Stack上,一个Stack中多个Task,一个Task包括多个Activity
最后调用ActivityTask的startActivityLocked启动
ActivityStack . startActivityLocked
final void startActivityLocked(ActivityRecord r, boolean newTask,boolean doResume, boolean keepCurTransition, Bundle options) {
//获取要启动的Task对象
TaskRecord rTask = r.task;
final int taskId = rTask.taskId;
TaskRecord task = null;
if (!newTask) {
//遍历AMS中全部的Task,找到目标task,然后将即将要启动的Activity增加到Task的栈顶
boolean startIt = true;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// All activities in task are finishing.
continue;
}
if (task == r.task) {
if (!startIt) {
task.addActivityToTop(r);
r.putInHistory();
……
//传入的resume位true。然后调用resumeTopActivitiesLocked方法继续启动Activity
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
遍历全部Task,找到目标Task,将即将要启动的Activity的ActivityRecord增加到栈顶
ActivityStackSuperVisor. resumeTopActivitiesLocked
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, Bundle targetOptions) {
//假设目标task是frontStack调用resumeTopActivityLocked
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
//然后遍历找到时frontStack的task运行resumeTopActivityLocked
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
……
}
if (isFrontStack(stack)) {
stack.resumeTopActivityLocked(null);
}
……
确认目标task是否为frontStack,若是则直接执行resumeTopActivityLocked,不是则遍历,找到对应的frontStack执行resumeTopActivityLocked
ActivityStack.resumeTopActivityLocked
直接有调用了resumeTopActivityInnerLocked方法
ActivityStack. resumeTopActivityInnerLocked
ActivityStack. resumeTopActivityInnerLocked private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
……
//找到栈顶第一个不是处于finishing状态的ActicityRecord
final ActivityRecord next = topRunningActivityLocked(null);
……
//调用startPausingLocked方法来暂停上一个Activity
if (mResumedActivity != null) {
if (DEBUG_STATES)
Slog.d(TAG_STATES,"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
topRunningActivityLocked找到当前栈顶不是处于fininshiing状态的第一个ActivityRecord
将B的ActivityRecord添加到当前Task的栈顶,即next
startPausingLocked暂停上一个Activity
ActivityStack有三个成员变量:mResumedActivity、mLastResumedActivity、mLastPausedActivity
- mResumedActivity:栈中激活状态的activity
- mLastResumedActivity:栈中上一次被暂停的activity
- mLastPausedActivity:栈中正在被暂停的activity
mResumedActivity != null表示A不为空,暂停A
总结 startActivity到Pause
Activity的startActivity方法启动目标Activity
Instrumentation的方法execStartActivity,方便Instrumentation对交互进行监測
以上部分是在App1的进程中运行。之后会通过进程间通信调用到AMS服务中调用AMS的startActivity方法。
此时进入SystemServer进程。
然后由AMS中管理Acticity核心调度的类ActivityStackSupervisor的方法startActivityMayWait来处理。该方法中主要是依据Intent从PMS中查询目标Activity的信息
ActivityStackSuperVisor的startActivityLocked方法主要是在AMS中找调用进程的processRecord信息,调用Activity的ActivityRecord信息。目标Activity还没有启动,所以须要先创建一个目标Activity的ActivityRecord信息。
ActivityStackSuperVisor的StartActivityUncheckedLocked方法主要来处理启动模式相关的逻辑,依据不同的启动模式,找到对应的对的ActivityStack,然后又对应的ActivityStack进行处理
ActivityStack将目标Activity增加到相应的Task栈顶
调用ActivityStackSuperVisor的resumeTopActivityLocked方法找到处于前台的Task。然后调用它的resumeTopActivityLocked方法激活目标Activity.
当前的Task的栈開始Pasuing调用的Activity
以上几个步骤完成AMS对调用Activity及目标Activity的信息收集处理
拿到启动进程的binder对象和A的activityRecord给AMS
通过ActivityStackSuperVisor拿到启动进程的信息
根据Intent拿到目标Activity的信息
依据启动模式来决定将目标Activity方法那个栈中。然后将目标栈当前处于激活状态的Activity Pause掉给目标Activity腾地方。
Activity Resume - Pause
ActivityStack.startPausingLocked
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,boolean dontWait) {
//mResumeActivity代表当前激活的Activity。即Activity A
ActivityRecord prev = mResumedActivity;
……
//当前处于激活状态mResumedActivity 的设置为null
mResumedActivity = null;
//即将要处于pasuing状态的Activity 就是Activity A
mPausingActivity = prev;
mLastPausedActivity = prev;
……
//将Activity A的状态设置为PAUSING
prev.state = ActivityState.PAUSING;
//找到当前的栈顶的topActivity就是 Activity B
final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
//调用进程不为null,且调用进程的ApplicationThread不为null
if (prev.app != null && prev.app.thread != null) {
try {
……
//通过调用进程的ApplicationThread通知调用进程schedulePauseActivity方法
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);
}
从mResumeActivity拿到A的ActivityRecord,赋值prev
并将其和B设为pause状态,因为B暂时未启动,未激活
prev.app代表A的ProcessRecord,prev.app.thread则为A所在进程的ApplicationThread
通过ApplicationThread可以得到进程的Binder client,使得AMS能够向应用进程发送消息
最终通过调用A的schedulePauseActivity,完成Pause
ApplicationThread. schedulePauseActivity
public final void schedulePauseActivity(IBinder token, boolean finished,boolean userLeaving, int configChanges, boolean dontReport) {
sendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,token,(userLeaving ?1 : 0) | (dontReport ? 2 : 0),configChanges);
}
应用进程的ApplicationThread是ActivityThread的一个内部类,token是一个Binder类型的对象,指向了AMS中与A的ActivityRecord,根据finish决定是暂停结束还是暂停
这里发送了PAUSE_ACTIVITY的message给handler
……
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,(msg.arg1&2) != 0);
ActivityThread.handPauseActivity
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
//调用Activity A的onPause方法
performPauseActivity(token, finished, r.isPreHoneycomb());
//等待pause状态的数据写入完毕.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
……
try {
//进程间通信。调用AMS的ActivityPause方法
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {}
ActivityThread中的mActivites集合中保存了当前进程的所有Activity,每个Activity都用一个ActivityClientRecord表示,集合中以binder为key保存
AMS中的全部Activity也是在一个集合中存储,以ActivityRecord来表示,key值也是Binder对象
此处由token获取获取ActivityClientRecord
performPauseActivity调用了A的onSaveInstance,然后调用了onPause
因为onSaveInstance需要存储当前Activity的信息,进行I/O操作,所以需要QueuedWork.waitToFinish来等待存储完成
最后调用activityPaused,进入SystemServer进程
AMS.activityPaused
public final void activityPaused(IBinder token) {
//获取Activity 所在的ActivityStack
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
//调用目标ActivityStack的activityPauseLocked方法
stack.activityPausedLocked(token, false);
}
}
Token代表的是Activity A ,此处依据token找到Activity A所在的ActivityStack,然后由目标Stack来处理activityPause逻辑
ActivityStack.activityPauseLocked
final void activityPausedLocked(IBinder token, boolean timeout) {
//依据token获取Activity A的ActivityRecord对象
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
//移除pause超时消息
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
//调用completePauseLocked方法继续运行pause逻辑
completePauseLocked(true);
}
……
当运行完pause逻辑的ActivityRecord和我们运行pause逻辑前的activityRecord一样的时候,即是同一个Activity。
就能够调用completePauseLocked方法来完毕Activity A Pause最后的逻辑了。
ActivityStack. completePauseLocked
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) {
mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
}
……
}
resumeNext就是completePauseLocked传进来的參数,为true。
调用mStackSupervisor的getFocusedStack()方法来获取正在处理的ActivityStack. mService.isSleepingOrShuttingDown。推断AMS服务是否处于正常激活状态
然后调用mStackSupervisor的resumeTopActivitiesLocked继续处理。
ActivityStackSuperVisor.resumeTopActivitiesLocked
假设当前的ActivityStack是frontStack。
直接调用ActivityStack的resumeTopActivityLocked。
ActivityStack的resumeTopActivityLocked方法则直接有调用了ActivityStack的resumeTopActivityInnerLocked方法。
ActivityStack. resumeTopActivityInnerLocked
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
……
//找到栈顶的Activity,此时栈顶的acitvity就是即将要启动的Activity B
final ActivityRecord next = topRunningActivityLocked(null);
……
//我们知道,在前面Activity A变为pause状态的时候。我们就把mResumeActivity 置为了Null
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
……
//即将要启动的Activity处于一个新的进程,眼下还没有启动
if (next.app != null && next.app.thread != null) {
……
}else{
……
//来启动目标Activity
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
推断mResumeActivity不为空,说明当前有一个处于正在激活状态的Activity,须要先将原先的Activity变为pause状态。
当Activity A变为Pause状态后。再次走到这种方法来激活目标Activity,此时mResumeActivity已经为空,所以不须要再运行pause的逻辑。
然后推断目标Activity next的进程app和ApplicationThread是否为空,由于Activity A 所在的进程还没有创建,所以两个都为空,直接运行mStackSupervisor的startSpecificActivityLocked来启动新的Activity。
此阶段由ActivityStack.startPausingLocked开始,将A进行Pause,调用onRestoreinstance保存信息等,修改当前的ActivityStack的激活activity等信息,然后定位B的ActivityStack,暂停栈顶Activity,并启动新进程
启动新进程
ActivityStackSuperVisor. startSpecificActivityLocked
void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {
//获取目标Activity的进程ProcessRecord
ProcessRecord app = mService.getProcessRecordLocked(r.processName,r.info.applicationInfo.uid, true);
……
//因为目标Activity所在进程还没有创建,所以为空
if (app != null && app.thread != null) {
……
}
//
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,"activity", r.intent.getComponent(), false, false, true);
}
该方法比較简单,依据目标Activity的ProcessName来查找相应的ProcessRecord.
依据processRecord中的进程app和ApplicationThread来推断
假设这两个变量不为空,说明目标Activity的进程和执行环境已经具备
直接启动Activity就能够,我们知道眼下目标Activity的进程还没有启动,所以须要调用AMS先启动一个目标Activity的进程
AMS. startProcessLocked
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,……) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
String hostingNameStr = hostingName != null?hostingName.flattenToShortString() :null
……
startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
……
}
……
}
获得ProcessRecord,调用startProcessLocked
private final void startProcessLocked(ProcessRecord app, String hostingType,String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
int uid = app.uid;
int[] gids = null;
……
//從PMS服务中查找目标应用相应的权限组
final IPackageManager pm = AppGlobals.getPackageManager();
permGids = pm.getPackageGids(app.info.packageName, app.userId);
……
gids = new int[permGids.length + 2];
System.arraycopy(permGids, 0, gids, 2, permGids.length);
……
app.gids = gids;
……
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
//调用Process的静态方法启动一个新的进程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
这种方法做的主要工作就是调用Process的静态方法启动一个新的进程。
启动新的进程的过程大概是
Zygote进程会fork一个新的子进程出来,子进程创建完毕之后
classLoader载入ActivityThread类并创建一个ActivityThread实例
反射调用ActivityThread的main方法
这样ActivityThread主线程就在新的进程中启动起来了。
接着看ActivityThread的main方法,此时已经在新的进程中运行了。
ActivityThread.main
public static void main(String[] args) {
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
这种方法主要工作就是调用Looper.prepareMainLooper创建一个消息循环队列
然后调用Looper.loop进入消息循环,当前线程进入消息循环中
使当前线程成为新进程的主线程,然后创建一个ActivityThread对象。调用Attach方法。
ActivityThread.attach
final ApplicationThread mAppThread = new ApplicationThread();
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
……
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
……
} else {
}
初始系统进程的执行环境的时传入的參数system为true,表示是系统进程
而这次是普通的应用进程,所以參数system为false
ActivityManagerNative.getDefault()方法获取AMS的代理
调用attachApplication方法发送一个进程间通信的请求,将创建的ApplicationThread对象传递给AMS服务
ApplicationThread是一个ActivityThread本地binder对象,Binder的服务端在ActivityThread中,将Binder对象传递给AMS服务。则AMS服务中保存它的代理,AMS就获得了与新进程通信的方式。
此前的代码运行在新建的进程中。即应用App2所在的进程,然后通过进程间通信
AMS.attachApplication
ApplicationInfo appInfo = app.instrumentationInfo != null? app.instrumentationInfo : app.info;
//进程间调用:调用新进程的bindApplication方法
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
……
if (normalMode) {
try {
//调用ActivityStackSupervisor的方法来启动新的Activity
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
}
……
}
依据进程ID,查询相应进程的ProcessRecord,这个ProcessRecord是新进程的对象,指向新进程
从PMS中查询与新进程相关的ContentProvider的信息
这里的thread是新进程的ApplicationThread的binder,调用新进程的handlebindApplication来初始化执行环境,包含新进程Application的初始化、Instrumentation的初始化和安装相关的ContentProvider
最后调用ActivityStackSupervisor执行attachApplication
ActivityStackSuperVisor. attachApplicationLocked
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
//遍历全部的stack,找到处于前台的ActivityStack
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack)) {
continue;
}
//找到处于栈顶的ActivityRecord
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid&& processName.equals(hr.processName)) {
try {
//调用realstartActivityLocked方法来启动目标Activity
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
……
}
}
遍历并找到目标stack,然后拿到这个ActivityStack栈顶的ActivityRecord,这就是目标Activity
之前放到栈顶的。得到要启动的Activity信息之后启动新的Activity
ActivityStackSuperVisor. realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r,ProcessRecord app, boolean andResume, boolean checkConfig)throws RemoteException {
……
//将新进程的信息保存到ActivityRecord的app变量中
r.app = app;
//获取目标Task
final TaskRecord task = r.task;
//找到Task对用的Stack
final ActivityStack stack = task.stack;
//跨进程调用,通知目标进程来启动Activity
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
}
将ActivityRecord的app对象指向了新的进程。这样ActivityRecord就和新的进程关联了起来。
然后通过目标进程ApplicationThread代理Binder对象发起进程间通信请求,调用目标进程的scheduleLaunchActivity方法来启动新的Activity
ApplicationThread. scheduleLaunchActivity
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig,…… ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
//依据进程间传递的消息,初始化ActivityClientRecord
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
……
//发送消息,终于有Handler来处理
sendMessage(H.LAUNCH_ACTIVITY, r);
}
调用到ActivityThread内部的ApplicationThread中
该ApplicationThread实现了ApplicationThreadNative,这样就实现了进程间通信的Binder服务端
发送消息,由Handler的HandMessage来处理
在handleMessage中又调用了ActivityThread的handleLaunchActivity来处理
ActivityThread.handleLaunchActivity
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//调用performLaunchActivity方法来启动Activity
Activity a = performLaunchActivity(r, customIntent);
//Activity启动完毕后。调用handlResumeActivity来使Activity进入resume激活状态
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed);
}
}
首先调用performLaunchActivity来创建一个Activity对象,并调用Activity的onCreate方法完毕Activity启动
随后调用handleResumeActivity方法。激活Activity,时Activity计入resume状态
ActivityThread.performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
//获取Activity的packageInfo信息
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);
}
//获取Activity的Component信息
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(mInitialApplication.getPackageManager());r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,r.activityInfo.targetActivity);
}
//调用Instrumentation类来创建一个依据Activity的信息Activity对象
Activity activity = null;
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
//创建完毕后,调用Activity的attach方法来初始化Activity
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Launching activity "+ r.activityInfo.name + " with config " + config);
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
……
//调用Activity的onCreate方法
mInstrumentation.callActivityOnCreate(activity, r.state);
……
//运行Activity的onStart方法
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
……
//调用Activity的onRestoreInstancestate方法
if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
……
//调用Activity的onPostCreate方法
mInstrumentation.callActivityOnPostCreate(activity, r.state);
……
//把创建的相应的ActivityClientRecord以binder为键值,保存到mActivities中
mActivities.put(r.token, r);
在新的进程中,依据AMS传递过来的信息创建了一个ActivityClientRecord对象。该对象和AMS服务中的一个ActivityRecord相应。
在这种方法中。依据目标Activity B的ActivityClientRecord,调用Instrumentation类来创建一个Acitivity,创建过程就是ClassLoader载入相应的Activity类,用反射方法创建一个对象。
创建完新的Activity对象后,即Activity B的对象,然后调用它的onCreate方法,这样Activity B的onCreate对象就会被调用,以便载入自定义的用户界面,以及其它的初始化方法。
onCreate方法调用完毕之后。
然后依次调用ActivityonStart,onRestoreInstanceState,onPostCreate方法等,这个就是Activity生命周期运行的逻辑。
创建新进程的总结:
通过Zygote创建新进程,在其main方法中创建消息队列和application。
创建Application传给AMS,查找目标Activity所在的stack,拿到位于栈顶的ActivtiyRecord,对新进程和ActivityRecord进行关联,通过发送消息调用ActivityThread调用handleLaunchActivity来调用performLaunchActivity完成activity的onCreate和activity的onResume
到此为止。ActivityB就启动完毕了,它启动起来之后,意味着ActivityB所在的应用程序也就启动起来了。