Activtiy完全解析(一、Activity的创建过程)

更新时间:2024-04-22 10:42:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Activtiy完全解析(一、Activity的创建

过程)

在Android开发过程中,我们几乎每天都在跟Activity打交道。我们循规蹈矩的调用startActivity()方法便可以打开一个新的界面,但是这个

界面是怎样从无到有我们却不是很清楚,也有很多人根本就没有想过。我们写的layout布局通过setContentView()方法是怎样加载到activity

中,然后又是怎样显示到界面上的?这一系列的问题相信大多数人都不清楚。

也许是因为我们平时的开发过程根本不需要了解这些,但是如果深入了解后,对我们还是很有帮助的。接下来我们用3篇文章去分析一下

Activity从无到显示布局这一过程,第一篇我们就深入研究一下Activity的创建过程。

step 1. Activity.startActivtiy()

在Android系统中,我们比较熟悉的打开Activity通常有两种方式,第一种是点击应用程序图标,Launcher会启动应用程序的主Activity,我们

知道Launcher其实也是一个应用程序,他是怎样打开我们的主Activity的呢?在应用程序被安装的时候,系统会找到AndroidManifest.xml中

activity的配置信息,并将action=android.intent.action.MAIN&category=android.intent.category.LAUNCHER的activity记录下来,形成应

用程序与主Activity 的映射关系,当点击启动图标时,Launcher就会找到应用程序对应的主activity并将它启动。第二种是当主Activity启动

之后,在应用程序内部可以调用startActivity()开启新的Activity,这种方式又可分为显示启动和隐式启动。不管使用哪种方式启动Activity

,其实最终调用的都是startActivity()方法。所以如果要分析Activity的启动过程,我们就从startActivity()方法分析。跟踪发现Activity

中重载的startActivity()方法最终都是调用startActivityForResult(intent, requestCode , bundle):

public void startActivityForResult(Intent intent, int requestCode, Bundle options) {

//一般Activity的mParent都为null,mParent常用在ActivityGroup中,ActivityGroup已废弃

if (mParent == null) {

//启动新的Activity

Instrumentation.ActivityResult ar =

mInstrumentation.execStartActivity(

this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) {

//跟踪execStartActivity(),发现开启activity失败ar才可能为null,这时会调用onActivityResult

mMainThread.sendActivityResult(

mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } ... } else {

//在ActivityGroup内部的Activity调用startActivity的时候会走到这里,处理逻辑和上面是类似的

if (options != null) {

mParent.startActivityFromChild(this, intent, requestCode, options); } else {

// Note we want to go through this method for compatibility with // existing applications that may have overridden it.

mParent.startActivityFromChild(this, intent, requestCode); } } }

从上面的代码可以发现,开启activity的关键代码是mInstrumentation.execStartActivity(),mInstrumentation是Activity的成员变量,用

于监视系统与应用的互交。

step2. Instrumentation.execStartActivity()

public ActivityResult execStartActivity(

Context who, IBinder contextThread, IBinder token, String target, Intent intent, int requestCode, Bundle options) {

IApplicationThread whoThread = (IApplicationThread) contextThread; //mActivityMonitors是所有ActivityMonitor的集合,用于监视应用的Activity(记录状态) if (mActivityMonitors != null) { synchronized (mSync) {

//先查找一遍看是否存在这个activity final int N = mActivityMonitors.size(); for (int i=0; i

final ActivityMonitor am = mActivityMonitors.get(i); if (am.match(who, null, intent)) {

//如果找到了就跳出循环 am.mHits++;

//如果目标activity无法打开,直接return if (am.isBlocking()) {

return requestCode >= 0 ? am.getResult() : null; }

break; } } } } try {

intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess();

//这里才是真正开启activity的地方,ActivityManagerNative中实际上调用的是ActivityManagerProxy的方法

int result = ActivityManagerNative.getDefault()

.startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target, requestCode, 0, null, options);

//checkStartActivityResult方法是抛异常专业户,它对上面开启activity的结果进行检查,如果无法打开activity,

//则抛出诸如ActivityNotFoundException类似的各种异常 checkStartActivityResult(result, intent); } catch (RemoteException e) {

throw new RuntimeException(\ }

return null; }

mInstrumentation的execStartActivity()方法中首先检查activity是否能打开,如果不能打开直接返回,否则继续调用

ActivityManagerNative.getDefault().startActivity()开启activity,然后检查开启结果,如果开启失败,会抛出异常(比如未在

AndroidManifest.xml注册)。接着我们转入ActivityManagerNative中:

step3. ActivityManagerNative

在讲解此步骤之前,先大致介绍一下ActivityManagerNative这个抽象类。ActivityManagerNative继承自Binder(实现了IBinder),实现了

IActivityManager接口,但是没有实现他的抽象方法。

ActivityManagerNative中有一个内部类ActivityManagerProxy,ActivityManagerProxy也实

现了IActivityManager接口,并实现了

IActivityManager中所有的方法。IActivityManager里面有很多像startActivity()、startService()、bindService()、registerReveicer()

等方法,它为Activity管理器提供了统一的API。

ActivityManagerNative通过getDefault()获取到一个ActivityManagerProxy的示例,并将远程代理对象IBinder传递给他,然后调用他的

starXxx方法开启Service、Activity或者registReceiver,可以看出ActivityManagerNative只是一个装饰类,真正工作的是其内部类

ActivityManagerProxy。

①.ActivtiyManagerNative.getDefault().startActivity()

static public IActivityManager getDefault() {

//此处返回的IActivityManager示例是ActivityManagerProxy的对象 return gDefault.get(); }

private static final Singleton gDefault = new Singleton() {

protected IActivityManager create() {

//android.os.ServiceManager中维护了HashMap sCache,他是系统Service对应的IBinder代理对象的集合

//通过名称获取到ActivityManagerService对应的IBinder远程代理对象 IBinder b = ServiceManager.getService(\ if (false) {

Log.v(\ }

//返回一个IActivityManager对象,这个对象实际上是ActivityManagerProxy的对象 IActivityManager am = asInterface(b); if (false) {

Log.v(\ }

return am; } };

static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; }

IActivityManager in =

(IActivityManager)obj.queryLocalInterface(descriptor);

if (in != null) { return in; }

//返回ActivityManagerProxy对象 return new ActivityManagerProxy(obj); }

ActivityManagerNative中的方法只是获取到ActivityManagerProxy的实例,然后调用其startActivity方法:

②.ActivtiyManagerProxy.startActivity()

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,

String resolvedType, IBinder resultTo, String resultWho, int requestCode,

int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {

Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain();

//下面的代码将参数持久化,便于ActivityManagerService中获取 data.writeInterfaceToken(IActivityManager.descriptor);

data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeString(callingPackage); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(startFlags); if (profilerInfo != null) { data.writeInt(1);

profilerInfo.writeToParcel(data,

Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else {

data.writeInt(0); }

if (options != null) { data.writeInt(1);

options.writeToParcel(data, 0); } else {

data.writeInt(0); }

//mRemote就是ActivityManagerService的远程代理对象,这句代码之后就进入到ActivityManagerService中了

mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);

reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; }

上面说到ActivityManagerNative才是真正干活的,他维护了ActivityManagerService的远程代理对象mRemote ,最终会通过mRemote将开启

Activity的消息传送给ActivityManagerService,这样就来到了ActivityManagerService的startActivity方法中:

step4. ActivityManagerService

public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...

@Override

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()); }

@Override

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) {

enforceNotIsolatedCaller(\

userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, \ //mStackSupervisor的类型是ActivityStackSupervisor

return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, options, userId, null, null);

}

... }

ActivityManagerService中startActivity()直接调用了startActivityAsUser()方法,这个方法中又调用了ActivitySupervisor的

startActivityMayWait()方法:

step5. ActivityStackSupervisor.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, int userId, IActivityContainer iContainer, TaskRecord inTask) { ...

// Don't modify the client's object! intent = new Intent(intent);

// 调用resolveActivity()根据意图intent参数,解析目标Activity的一些信息保存到aInfo中,

// 这些信息包括activity的name、applicationInfo、processName、theme、launchMode、permission、flags等等

// 这都是在AndroidManifest.xml中为activity配置的

ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);

...

synchronized (mService) {

//下面省略的代码用于重新组织startActivityLocked()方法需要的参数 ...

//调用startActivityLocked开启目标activity

int res = startActivityLocked(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, componentSpecified, null, container, inTask);

...

if (outResult != null) {

//如果outResult不为null,则设置开启activity的结果 outResult.result = res; ...

return res; } }

根据上面传递的参数和应用信息重新封装一些参数,然后调用startActivityLocked()方法:

step6. ActivityStackSupervisor.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 componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,

TaskRecord inTask) { int err = ActivityManager.START_SUCCESS;

//调用者的进程信息,也就是哪个进程要开启此Activity的 ProcessRecord callerApp = null;

//下面有很多if语句,用于判断一些错误信息,并给err赋值相应的错误码 if (caller != null) {

callerApp = mService.getRecordForAppLocked(caller); if (callerApp != null) {

callingPid = callerApp.pid;

callingUid = callerApp.info.uid; } else {

err = ActivityManager.START_PERMISSION_DENIED; } } ...

if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) { err = ActivityManager.START_INTENT_NOT_RESOLVED; }

if (err == ActivityManager.START_SUCCESS && aInfo == null) { // 未找到需要打开的activity的class文件

err = ActivityManager.START_CLASS_NOT_FOUND; } ...

//上面判断完成之后,接着判断如果err不为START_SUCCESS,则说明开启activity失败,直接返回错误码

if (err != ActivityManager.START_SUCCESS) { if (resultRecord != null) {

resultStack.sendActivityResultLocked(-1,

resultRecord, resultWho, requestCode, Activity.RESULT_CANCELED, null); }

ActivityOptions.abort(options); return err; }

//检查权限,有些activity在清单文件中注册了权限,比如要开启系统相机,就需要注册相机权限,否则此处就会跑出异常

final int startAnyPerm = mService.checkPermission(

START_ANY_ACTIVITY, callingPid, callingUid);

final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,

callingUid, aInfo.applicationInfo.uid, aInfo.exported);

if (startAnyPerm != PERMISSION_GRANTED && componentPerm != PERMISSION_GRANTED) {

if (resultRecord != null) {

resultStack.sendActivityResultLocked(-1,

resultRecord, resultWho, requestCode, Activity.RESULT_CANCELED, null); }

String msg;

//权限被拒绝,抛出异常 if (!aInfo.exported) {

msg = \ + \ + \

+ \ } else {

msg = \ + \ + \ + \ }

throw new SecurityException(msg); }

//★★★经过上面的判断后,创建一个新的Activity记录,

// 这个ActivityRecord就是被创建的activity在历史堆栈中的一个条目,表示一个活动 ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, this, container, options); ...

//继续调用startActivityUncheckedLocked()

err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask); ...

return err; }

这个方法主要是判断一些错误信息和检查权限,如果没有发现错误(err==START_SUCCESS)就继续开启activity, 否则直接返回错误码。继续

查看startActivityUnChechedLocked()方法:

step7 : ActivityStackSupervisor.startActivityUncheckedLocked()

final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int

startFlags,

boolean doResume, Bundle options, TaskRecord inTask) { ...

//① 获取并配置activity配置的启动模式 int launchFlags = intent.getFlags();

if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 && (launchSingleInstance || launchSingleTask)) { launchFlags &=

~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); } else { ... } ... /*

* 如果调用者不是来自另一个activity(不是在activity中调用startActivity), * 但是给了我们用于放入心activity的一个明确的task,将执行下面代码 *

* 我们往上追溯,发现inTask是step4 中 ActivityManagerService.startActivityAsUser()

方法传递的null,

* 所以if里面的不会执行 */

if (sourceRecord == null && inTask != null && inTask.stack != null) { ... } else {

inTask = null; }

//根据activity的设置,如果满足下列条件,将launchFlags置为FLAG_ACTIVITY_NEW_TASK(创建新进程) if (inTask == null) {

if (sourceRecord == null) {

// This activity is not being started from another... in this // case we -always- start a new task.

//如果调用者为null,将launchFlags置为 创建一个新进程

if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {

launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; }

} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {

// 如果调用者的模式是SINGLE_INSTANCE,需要开启新进程 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; } else if (launchSingleInstance || launchSingleTask) {

// 如果需要开启的activity的模式是SingleInstance或者SingleTask,也需要开新进程

launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK; } }

ActivityInfo newTaskInfo = null; //新进程 Intent newTaskIntent = null;

ActivityStack sourceStack; //调用者所在的进程 //下面省略的代码是为上面三个变量赋值 ...

/*

* ② 我们尝试将新的activity放在一个现有的任务中。但是如果activity被要求是singleTask或者singleInstance,

* 我们会将activity放入一个新的task中.下面的if中主要处理将目标进程置于栈顶,然后将目标activity显示 */

if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&

(launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)

|| launchSingleInstance || launchSingleTask) { //如果被开启的activity不是需要开启新的进程,而是single instance或者singleTask, if (inTask == null && r.resultTo == null) {

//检查此activity是否已经开启了,findTaskLocked()方法用于查找目标activity所在的进程

ActivityRecord intentActivity = !launchSingleInstance ?

findTaskLocked(r) : findActivityLocked(intent, r.info); if (intentActivity != null) { ...

targetStack = intentActivity.task.stack; ...

//如果目标activity已经开启,目标进程不在堆栈顶端,我们需要将它置顶

final ActivityStack lastStack = getLastStack(); ActivityRecord curTop = lastStack == null? null : lastStack.topRunningNonDelayedActivityLocked(notTop); boolean movedToFront = false;

if (curTop != null && (curTop.task != intentActivity.task || curTop.task != lastStack.topTask())) {

r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); if (sourceRecord == null || (sourceStack.topActivity() != null && sourceStack.topActivity().task == sourceRecord.task)) { ...

//置顶进程

targetStack.moveTaskToFrontLocked(intentActivity.task, r, options, \ ...

movedToFront = true; } } ...

if ((launchFlags &

(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) ==

(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TASK)) { //如果调用者要求完全替代已经存在的进程 reuseTask = intentActivity.task;

reuseTask.performClearTaskLocked(); reuseTask.setIntent(r);

} else if ((launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0 || launchSingleInstance || launchSingleTask) {

//将进程堆栈中位于目标activity上面的其他activitys清理掉

ActivityRecord top = intentActivity.task.performClearTaskLocked(r,

launchFlags);

} else if (r.realActivity.equals(intentActivity.task.realActivity)) {

//如果进程最上面的activity就是目标activity,进行一些设置操作 ... } else if ((launchFlags&Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) == 0) { ...

} else if (!intentActivity.task.rootWasReset) { ... }

if (!addingToTask && reuseTask == null) {

//让目标activity显示,会调用onResume if (doResume) {

targetStack.resumeTopActivityLocked(null, options); } else {

ActivityOptions.abort(options); }

//直接返回

return ActivityManager.START_TASK_TO_FRONT; } } } }

// ③ 判断包名是否解析成功,如果包名解析不成功无法开启activity if (r.packageName != null) {

//当前处于堆栈顶端的进程和activity

ActivityStack topStack = getFocusedStack();

ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop); if (top != null && r.resultTo == null) {

if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) { if (top.app != null && top.app.thread != null) {

if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0 || launchSingleTop || launchSingleTask) {

ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,

top.task); ...

return ActivityManager.START_DELIVERED_TO_TOP; } } } }

} else {

// 包名为空,直接返回,没有找到要打开的activity ...

return ActivityManager.START_CLASS_NOT_FOUND; }

// ④ 判断activiy应该在那个进程中启动,如果该进程中已经存在目标activity,根据启动模式做相应处理 ...

// 判断是否需要开启新进程? boolean newTask = false;

if (r.resultTo == null && inTask == null && !addingToTask

&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { ...

newTask = true; //如果有FLAG_ACTIVITY_NEW_TASK标志,将为目标activity开启新的进程

targetStack = adjustStackFocus(r, newTask); if (!launchTaskBehind) {

targetStack.moveToFront(\ }

if (reuseTask == null) {

r.setTask(targetStack.createTaskRecord(getNextTaskId(), newTaskInfo != null ? newTaskInfo : r.info, newTaskIntent != null ? newTaskIntent : intent,

voiceSession, voiceInteractor, !launchTaskBehind /* toTop */), taskToAffiliate);

if (DEBUG_TASKS) Slog.v(TAG, \ r.task); } else {

r.setTask(reuseTask, taskToAffiliate); } ...

} else if (sourceRecord != null) { //调用者不为空

final TaskRecord sourceTask = sourceRecord.task; //默认在调用者所在进程启动,需要将进程置前 targetStack = sourceTask.stack;

targetStack.moveToFront(\ final TaskRecord topTask = targetStack.topTask(); if (topTask != sourceTask) {

targetStack.moveTaskToFrontLocked(sourceTask, r, options, \ }

if (!addingToTask && (launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {

//没有FLAG_ACTIVITY_CLEAR_TOP标志时,开启activity

ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags); if (top != null) {

ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);

top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage); ...

targetStack.resumeTopActivityLocked(null);

return ActivityManager.START_DELIVERED_TO_TOP; }

} else if (!addingToTask &&

(launchFlags&Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) { //如果activity在当前进程中已经开启,清除位于他之上的activity final ActivityRecord top = sourceTask.findActivityInHistoryLocked(r); if (top != null) {

final TaskRecord task = top.task;

task.moveActivityToFrontLocked(top);

ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, task); ...

return ActivityManager.START_DELIVERED_TO_TOP; } }

r.setTask(sourceTask, null);

if (DEBUG_TASKS) Slog.v(TAG, \r.task + \

sourceRecord);

} else if (inTask != null) {

//在调用者指定的确定的进程中开启目标activity ...

if (DEBUG_TASKS) Slog.v(TAG, \ + \r.task);

} else { ... }

...

ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task); targetStack.mLastPausedActivity = null;

//⑤ 继续调用目标堆栈ActivityStack的startActivityLocked()方法,这个方法没有返回值,执行完毕之后直接返回START_SUCCESS

targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options); if (!launchTaskBehind) {

// Don't set focus on an activity that's going to the back. mService.setFocusedActivityLocked(r, \ }

return ActivityManager.START_SUCCESS; }

通过第6步,新的activity记录已经创建了,接下来就是将这个activity放入到某个进程堆栈中;

startActivityLocked()中首先获取activity的启动模式(AndroidManifest.xml中为activity配置的launchMode属性值),

启动模式一共有四种:

ActivityInfo.LAUNCH_MULTIPLE(standard标准)、 ActivityInfo.LAUNCH_SINGLE_INSTANCE(全局单例)、 ActivityInfo.LAUNCH_SINGLE_TASK(进程中单例)、 ActivityInfo.LAUNCH_SINGLE_TOP(栈顶单例) 不清楚的可以参考官方网站:

http://developer.android.com/reference/android/content/pm/ActivityInfo.html 如果目标activity已经在某个历史进程中存在,需要根据启动模式分别判断并做相应处理。举个例子:如果启动模式为

LAUNCH_SINGLE_INSTANCE,发现目标activity在某个进程中已经被启动过,这时候就将此进程置于进程堆栈栈顶,然后清除位于目标activity

之上的activity,这样目标activity就位于栈顶了,这种情况就算是activity启动成功,直接返回。

通过上面的判断处理,发现必须创建新的activity,并将其放入到某个进程中,就会进一步获取需要栖息的进程堆栈targetStack(创建新进

程or已有的进程),最后调用(ActivityStack)targetStack.startActivityLocked()方法:

step8 : ActivityStack.startActivityLocked()

ActivityStack用于管理activity的堆栈状态,startActivityLocked()方法就是将某个activity记录放入堆栈中,下面看看源码:

final void startActivityLocked(ActivityRecord r, boolean newTask,

boolean doResume, boolean keepCurTransition, Bundle options) {

TaskRecord rTask = r.task; final int taskId = rTask.taskId;

// mLaunchTaskBehind tasks get placed at the back of the task stack.

if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {

// Last activity in task had been removed or ActivityManagerService is reusing task. // Insert or replace.

// Might not even be in. insertTaskAtTop(rTask);

mWindowManager.moveTaskToTop(taskId); }

TaskRecord task = null;

//①.不用创建新进程的情况,需要做一些任务切换操作 if (!newTask) {

boolean startIt = true;

//遍历所有的任务,找到目标activity所在的堆栈,taskNdx为所有的task的数量,肯定是大于0

for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { task = mTaskHistory.get(taskNdx); if (task.getTopActivity() == null) {

// 如果进程中activity为空,继续遍历 continue; }

if (task == r.task) {

//如果当前task==需要开启的activity的进程 if (!startIt) {

if (DEBUG_ADD_REMOVE) Slog.i(TAG, \task \

+ task, new RuntimeException(\ // 将需要启动的activity的记录放入task堆栈的顶层 task.addActivityToTop(r); r.putInHistory();

mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,

r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,

r.userId, r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind); ... return; }

break;

} else if (task.numFullscreen > 0) { startIt = false; } } }

//②. 在处于栈顶的进程中放置新的activity,这个activity将是即将和用户交互的界面 task = r.task;

//将activity插入历史堆栈顶层 task.addActivityToTop(r); task.setFrontOfTask(); r.putInHistory();

if (!isHomeStack() || numActivities() > 0) { /*

* 如果我们需要切换到一个新的任务,或者下一个activity不是当前正在运行的, * 我们需要显示启动预览窗口,在这里可能执行一切窗口切换的动画效果 */

boolean showStartingIcon = newTask; ProcessRecord proc = r.app; ...

if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) { mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, keepCurTransition);

mNoAnimActivities.add(r); } else {

//执行切换动画

mWindowManager.prepareAppTransition(...); mNoAnimActivities.remove(r); }

mWindowManager.addAppToken(task.mActivities.indexOf(r),

r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,

(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,

r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind); ... } else { /*

* 如果需要启动的activity的信息已经是堆栈中第一个,不需要执行动画 */

mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,

(r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId,

r.info.configChanges, task.voiceSession != null, r.mLaunchTaskBehind); ... } ...

if (doResume) {

//此处的doResume参数为true,继续调用ActivityStackSupervisor.resumeTopActivitiesLocked()

mStackSupervisor.resumeTopActivitiesLocked(this, r, options); }

}

这个方法中主要进行一些堆栈切换工作,将目标activity所在的堆栈置顶, 然后再栈顶放入新的activtiy记录,最后调用

mStackSupervisor.resumeTopActivitiesLocked(this, r, options)方法 将位于栈顶的activity显示出来:

step9 : ActivityStackSupervisor.resumeTopActivitiesLocked()

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, Bundle targetOptions) { if (targetStack == null) {

targetStack = getFocusedStack(); }

// Do targetStack first. boolean result = false; //是否是栈顶的任务

if (isFrontStack(targetStack)) {

result = targetStack.resumeTopActivityLocked(target, targetOptions); }

for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { final ArrayList stacks mActivityDisplays.valueAt(displayNdx).mStacks;

for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = stacks.get(stackNdx); if (stack == targetStack) { // Already started above. continue; }

if (isFrontStack(stack)) {

//会调用resumeTopActivityLocked(ActivityRecord prev, Bundle options) stack.resumeTopActivityLocked(null); } } }

return result; }

这一步紧接着调用ActivityStack.resumeTopActivityLocked():

step10 : ActivityStack.resumeTopActivityLocked()

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) { if (mStackSupervisor.inResumeTopActivity) { // Don't even start recursing.

= return false; }

boolean result = false; try {

// Protect against recursion.

mStackSupervisor.inResumeTopActivity = true; if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) { mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN; mService.updateSleepIfNeededLocked(); }

//继续调用resumeTopActivityInnerLocked()

result = resumeTopActivityInnerLocked(prev, options); } finally {

mStackSupervisor.inResumeTopActivity = false; }

return result; }

resumeTopActivityLocked()方法继续调用resumeTopActivityInnerLocked()方法:

final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) { ...

// We need to start pausing the current activity so the top one // can be resumed...

//① 需要将现在的activity置于pausing状态,然后才能将栈顶的activity处于resume状态

boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0; boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);

if (mResumedActivity != null) {

if (DEBUG_STATES) Slog.d(TAG, \Pausing \+ mResumedActivity);

pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause); } ...

// Launching this app's activity, make sure the app is no longer // considered stopped. //② 启动栈顶的activity

if (false) {

Looper.myLooper().setMessageLogging(new

LogPrinter(Log.DEBUG, \ } ...

//进入消息循环 Looper.loop();

throw new RuntimeException(\ }

private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { ... /*

* ActivityManagerNative.getDefault()方法返回的是一个ActivityManagerProxy对象,

* ActivityManagerProxy实现了IActivityManager接口,并维护了一个mRemote,

* 这个mRemote就是ActivityManagerService的远程代理对象 */

final IActivityManager mgr = ActivityManagerNative.getDefault(); try {

//调用attachApplication(),并将mAppThread传入,mAppThread是ApplicationThread类的示例,他的作用是用来进程间通 信的

mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } ... } else { ... } ... } }

ActivityThread是应用程序进程中的主线程,他的作用是调度和执行activities、广播和其他操作。 main方法开启了消息循环机制,并调用

attach()方法,attach()方法会调用ActivityManagerNative.getDefault()获取到一个ActivityManagerProxy示例,上面step3中我们讲解了

ActivityManagerNative这个类,ActivityManagerProxy中维护了ActivityManagerService的远程代理对象mRemote; 然后会调用

attachApplication()方法通过mRemote调用到ActivityManagerService的attachApplication()中, 传入的mAppThread是ApplicationThread类

型,mAppThread实际上通过Handler实现ActivityManagerService与ActivityThread的消息通信。

step14: ActivityManagerProxy.attachApplication() (ActivityManagerNative内部类)

public void attachApplication(IApplicationThread app) throws RemoteException {

Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain();

data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(app.asBinder());

mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0); reply.readException(); data.recycle(); reply.recycle(); }

attachApplication()接受IApplicationThread实例,step13中attach()方法传入的ApplicationThread实现了IApplicationThread,然后通过

ActivityManagerService的远程代理对象mRemote,进入ActivityManagerService的attachApplication():

step15: ActivityManagerService.attachApplication()

@Override

public final void attachApplication(IApplicationThread thread) { synchronized (this) {

int callingPid = Binder.getCallingPid();

final long origId = Binder.clearCallingIdentity();

//接着调用attachAppwww.shanxiwang.netlicationLocked() attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { //① 获取到进程 ProcessRecord app;

if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } } else {

app = null; }

if (app == null) {

if (pid > 0 && pid != MY_PID) { ...

Process.killProcessQuiet(pid); } else {

thread.scheduleExit(); ... }

return false; } ...

//② 对app的一些成员变量进行初始化 app.makeActive(thread, mProcessStats); app.curAdj = app.setAdj = -100;

app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; app.forcingToForeground = null;

updateProcessForegroundLocked(app, false, false); app.hasShownUi = false; app.debugging = false; app.cached = false;

app.killedByAm = false;

...

boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); ...

boolean badApp = false;

boolean didSomething = false;

// See if the top visible activity is waiting to run in this process... /*

* ③ 检查当前进程中顶端的activity是否等着被运行,这个顶端的activity就是我们要启动的activity; *

* 此处适用于需要为activity创建新进程的情况(比如点击Launcher桌面上的图标启动应用,或者打开配置了process的activity) *

* 如果应用程序已经启动,在应用程序内部启动activity(未配置process)不会创建进程,这种情况回到step11中的第①步直接开启

activity */

if (normalMode) { try {

if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; }

} catch (Exception e) {

Slog.wtf(TAG, \ badApp = true; } }

// Find any services that should be running in this process... //④ 查找当前进程中应该启动的服务,并将其启动 if (!badApp) { try {

didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) {

Slog.wtf(TAG, \ badApp = true; } }

// Check if a next-broadcast receiver is in this process... //⑤ 查找当前进程中应该注册的广播

if (!badApp && isPendingBroadcastProcessLocked(pid)) { try {

didSomething |= sendPendingBroadcastsLocked(app); } catch (Exception e) {

// If the app died trying to launch the receiver we declare it 'bad'

Slog.wtf(TAG, \ badApp = true; } }

// Check whether the next backup agent is in this process... ...

return true; }

attachApplication()方法调用了attachApplicationLocked()方法, 在step12中,我们创建了一个ProcessRecord,这里通过进程的pid将他取

出来,赋值给app, 并初始化app的一些成员变量,然后为当前进程启动顶层activity、一些服务和广播; 这里我们就不深入研究到底启动的是

那些,我们主要研究activity的启动,所以重点看第③步,_ step6_中最后创建了一个ActivityRecord实例r,这个r只是进程堆栈中的一个活

动记录, 然后再step8中将这个r插入到堆栈最顶端,所以这个r相当于一个占位,并不是真正启动的Activity, 真正启动Activity需要判断进

程是否存在,如果存在就直接启动,如果不存在需要启动进程后再执行此处第③步调用ActivityStackSupervisor.attachApplicationLocked

(ProcessRecord)方法:

step16: ActivityStackSupervisor.attachApplicationLocked(ProcessRecord)

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false;

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; } // /*

* 获取位于顶层堆栈中栈顶的activity,这个activity就是目标activity(需要被启动的);

* 这个hr就是step6中创建的ActivityRecord实例r */

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,同step11中的

第①步

if (realStartActivityLocked(hr, app, true, true)) { didSomething = true; }

} catch (RemoteException e) {

Slog.w(TAG, \ + hr.intent.getComponent().flattenToShortString(), e); throw e; } } } } }

if (!didSomething) {

ensureActivitiesVisibleLocked(null, 0); }

return didSomething; }

这个方法中首先遍历进程中的堆栈,找到位于顶层的堆栈,然后调用topRunningActivityLocked() 获取位于栈顶的ActivityRecord记录,最后

调用realStartActivityLocked()方法启动activity:

★★★step17: ActivityStackSupervisor.realStartActivityLocked()

final boolean realStartActivityLocked(ActivityRecord r,

ProcessRecord app, boolean andResume, boolean checkConfig)

throws RemoteException { ...

r.app = app; ...

int idx = app.activities.indexOf(r); if (idx < 0) {

app.activities.add(r); }

final ActivityStack stack = r.task.stack;

try { ...

List results = null;

List newIntents = null;

if (andResume) {

results = r.results;

newIntents = r.newIntents; } ... //

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),

r.compat, r.launchedFromPackage, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo); ...

} catch (RemoteException e) { if (r.launchFailed) {

//This is the second time we failed -- finish activity and give up. ...

return false; }

// This is the first time we failed -- restart process and retry. app.activities.remove(r); throw e; } ...

return true; }

这个方法调用app.thread.scheduleLaunchActivity()真正的启动一个activity, 这里thread是IApplicationThread的实例,也就是

ActivityThread中的成员变量ApplicationThread mAppThread; 在step15的第②步初始化app时调用app.makeActive(thread, mProcessStats)

为其赋值的。 我们接着看看ApplicationThread.scheduleLaunchActivity():

step18: ApplicationThread.scheduleLaunchActivity()

@Override

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,

ActivityInfo info, Configuration curConfig, Configuration overrideConfig,

CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,

int procState, Bundle state, PersistableBundle

persistentState,

List pendingResults, List pendingNewIntents,

boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

updateProcessState(procState, false);

ActivityClientRecord r = new ActivityClientRecord();

r.token = token; r.ident = ident; r.intent = intent; r.referrer = referrer;

r.voiceInteractor = voiceInteractor; r.activityInfo = info;

r.compatInfo = compatInfo; r.state = state;

r.persistentState = persistentState;

r.pendingResults = pendingResults; r.pendingIntents = pendingNewIntents;

r.startsNotResumed = notResumed; r.isForward = isForward;

r.profilerInfo = profilerInfo;

r.overrideConfig = overrideConfig;

updatePendingConfiguration(curConfig);

sendMessage(H.LAUNCH_ACTIVITY, r); }

ActivityThread中有一个H的成员变量,它是一个Handler, 专门接受ApplicationThread发送的消息,然后调用ActivityThread中的方法, 我

们看看H是怎样处理消息的:

step19:ActivityThread.H

public final class ActivityThread { ...

final ApplicationThread mAppThread = new ApplicationThread(); final H mH = new H();

private void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } ...

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) { if (DEBUG_MESSAGES) Slog.v(

TAG, \ + \ Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) {

msg.setAsynchronous(true); }

mH.sendMessage(msg); }

private class H extends Handler {

public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, \handling: \+ codeToString(msg.what));

switch (msg.what) {

case LAUNCH_ACTIVITY: { //启动activity ...

handleLaunchActivity(r, null); ... }

break;

case RELAUNCH_ACTIVITY: { //重新启动activity ...

handleRelaunchActivity(r); ... }

break;

case PAUSE_ACTIVITY: //activity失去焦点 ...

handlePauseActivity((IBinder) msg.obj, false, (msg.arg1 & 1) != 0, msg.arg2,

(msg.arg1 & 2) != 0); ... break; ...

case RESUME_ACTIVITY: //activity获取焦点

Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, \

handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... } } } }

step18中调用sendMessage(H.LAUNCH_ACTIVITY, r)之后,mH会收到一个LAUNCH_ACTIVITY消息, 然后调用了

ActivityThread.handleLaunchActivity(r, null):

step20:ActivityThread.handleLaunchActivity(r, null)

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...

//创建Activity对象,并初始化,然后调用activity.attach()和onCreate() Activity a = performLaunchActivity(r, customIntent); if (a != null) {

r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; //调用activity.onResume()

handleResumeActivity(r.token, false, r.isForward,

!r.activity.mFinished && !r.startsNotResumed);

... } else { ... } }

这里首先调用performLaunchActivity()方法创建Activity对象(调用它的attach()和onCreate()方法), 然后调用handleResumeActivity函数

来使这个Activity进入Resumed状态,并回调这个Activity的onResume函数。我们接着看看performLaunchActivity()方法中做了什么:

step21: ActivityThread.performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { //① 收集要启动的Activity的相关信息,主要package和component

ActivityInfo aInfo = r.activityInfo; ...

ComponentName component = r.intent.getComponent(); ...

Activity activity = null; try {

//② 通过类加载器将activity的类加载进来,然后创建activity对象 java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); activity = mInstrumentation.newActivity(

cl, component.getClassName(), r.intent);

StrictMode.incrementExpectedActivityCount(activity.getClass()); r.intent.setExtrasClassLoader(cl); r.intent.prepareToEnterProcess(); if (r.state != null) {

r.state.setClassLoader(cl); }

} catch (Exception e) { ... }

try {

//③ 创建Application,也就是AndroidManifest.xml配置的 Application app = r.packageInfo.makeApplication(false, mInstrumentation); ...

if (activity != null) {

//④ 创建Activity的上下文Content,并通过attach方法将这些信息设置到Activity中去

Context appContext = createBaseContextForActivity(r, activity);

CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration);

//⑤ 调用activity的attach()方法,这个方法的作用主要是为activity初始化一些成员变量

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);

if (customIntent != null) {

activity.mIntent = customIntent; }

r.lastNonConfigurationInstances = null; activity.mStartedActivity = false;

int theme = r.activityInfo.getThemeResource(); if (theme != 0) {

activity.setTheme(theme); }

activity.mCalled = false; /*

* ⑥ 通过mInstrumentation调用activity的onCreate()方法,

* mInstrumentation的作用是监控Activity与系统的交互操做。 * 这时候activity的生命周期就开始了 */

if (r.isPersistable()) {

mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else {

mInstrumentation.callActivityOnCreate(activity, r.state); }

//下面主要为堆栈中的ActivityClientRecord设置一些数据 ...

r.activity = activity; r.stopped = true;

if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; } ... }

r.paused = true; ...

} catch (SuperNotCalledException e) { throw e;

} catch (Exception e) {

if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException(

\ + \ } }

return activity; }

performLaunchActivity ()中首先根据activity的className加载类文件,并创建activity实例,然后初始化上下文Context,并调用attach()

方法初始化activity,最后通过mInstrumentation回调activity的onCreate()方法,这样Activity算是创建完成了。

这篇博客涉及到的内容还是比较多,每个过程中主要的代码注释已经标示的比较清楚了,还有些细节问题有兴趣的可以更加深入的去研究,

相信如果弄懂这个流程后,再去深入也不是什么难事了。项目中framwork层的源码都是参照android5.0版本,如果下载源码有问题的同学可以

在本篇博客末尾下载博客研究的工程(主要的源码已经摘录放入到工程中),也可以参考

http://grepcode.com/project/repository.grepcode.com/java/ext/com.google.android/android/。

接下来对本篇博客稍作总结:

step1-step3:通过Binder机制将创建activity的消息传给ActivityManagerService

step4-step8:根据activity的启动模式判断activity是否应该重新创建,还是只需要置于栈顶,并将目标activity记录放在栈顶

step9-step10:判断activity是否已经创建,如果已经创建将直接置于resume状态,如果没有创建便重新开启

step11-step12:判断activity所属的进程是否创建,如果没有创建将启动新的进程,如果创建了就直接启动activity

step13-step15:进程的主线程执行ActivityThread的main方法,然后初始化进程相关的东西

step16-step21:实例化栈顶的activity对象,并调用Activity.attach()初始化,回调onCreate()生命周期方法;然后调用

ActivityThread.handleResumeActivity()使activity处于resume状态

本文来源:https://www.bwwdw.com/article/xtwp.html

Top