文章目录
- 一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;
- Step 1. Launcher.startActivitySafely()
- Step 2. Activity.startActivity()
- Step 3. Activity.startActivityForResult()
- Step 4. Instrumentation.execStartActivity
- Step 5. ActivityManagerProxy.startActivity
- Step 6. ActivityManagerService.startActivity
- Step 7. ActivityStackSupervisor.startActivityMayWait
- 一、ActivityStackSupervisor.java (frameworks\base\services\core\java\com\android\server\am)
- Step 8. ActivityStack.startActivityLocked
- 二、startActivityLocked分析
- Step 9. ActivityStackSupervisor.startActivityUncheckedLocked
- Step 10. ActivityStack.resumeTopActivityLocked
- Step 11. ActivityStack.startPausingLocked
- 一、
- 二. Step 12 - Step 16:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;
- Step 12. ApplicationThreadProxy.schedulePauseActivity
- Step 13. ApplicationThread.schedulePauseActivity
- Step 14. ActivityThread.SendMessage
- Step 15. H.handleMessage
- Step 16. ActivityThread.handlePauseActivity
- 三. Step 17 - Step 24:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行;
- Step 17. ActivityManagerProxy.activityPaused
- Step 18. ActivityManagerService.activityPaused
- Step 19. ActivityStack.activityPausedLocked
- Step 20. ActivityStack.completePauseLocked
- Step 21. ActivityStack.resumeTopActivityLokced
- Step 22. ActivityStackSupervisor.startSpecificActivityLocked
- Step 23. ActivityManagerService.startProcessLocked
- Step 24. ActivityThread.main
- 四. Step 25 - Step 27:ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;
- Step 25. ActivityManagerProxy.attachApplication
- Step 26. ActivityManagerService.attachApplication
- Step 27. ActivityManagerService.attachApplicationLocked
- 五. Step 28 - Step 35:ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。
- Step 28. ActivityStack.realStartActivityLocked
- Step 29. ApplicationThreadProxy.scheduleLaunchActivity
- Step 30. ActivityThread.scheduleLaunchActivity
- Step 31. ActivityThread.SendMessage
- Step 32. H.handleMessage
- Step 33. ActivityThread.handleLaunchActivity
- Step 34. ActivityThread.performLaunchActivity
- Step 35. MainActivity.onCreate
- 整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段:
这篇是通过Launcher启动一个activity的过程,先以一张开头:
一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;
Step 1. Launcher.startActivitySafely()
在Android系统中,Launcher会将对应的应用程序启动起来。
public boolean startActivitySafely(View v, Intent intent, Object tag) {
boolean success = false;
try {
success = startActivity(v, intent, tag);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
}
return success;
}
Step 2. Activity.startActivity()
Launcher继承于Activity类,而Activity类实现了startActivity函数,因此,这里就调用了Activity.startActivity函数。
Activity.java (frameworks\base\core\java\android\app)
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
//startActivityForResult来进一步处理,第二个参数传入-1表示不需要这个Actvity结束后的返回结果。
startActivityForResult(intent, -1);
}
}
Step 3. Activity.startActivityForResult()
public void startActivityForResult(
String who, Intent intent, int requestCode, @Nullable Bundle options) {
Uri referrer = onProvideReferrer();
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, who,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, who, requestCode,
ar.getResultCode(), ar.getResultData());
}
cancelInputsAndStartExitTransition(options);
}
1、这里的mInstrumentation是Activity类的成员变量,它的类型是Intrumentation,定义在frameworks/base/core/java/android/app/Instrumentation.java文件中,它用来监控应用程序和系统的交互。
2、这里的mMainThread也是Activity类的成员变量,它的类型是ActivityThread,它代表的是应用程序的主线程,这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象,后面我们会看到,ActivityManagerService会使用它来和ActivityThread来进行进程间通信。这里的mMainThread代表的是Launcher应用程序运行的进程。
3、这里的mToken也是Activity类的成员变量,它是一个Binder对象的远程接口。
Step 4. Instrumentation.execStartActivity
Intrumentation用来监控应用程序和系统的交互
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, String target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
if (mActivityMonitors != null) {
......
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
// ActivityManagerNative.getDefault返回ActivityManagerService的远程接口,即ActivityManagerProxy接口
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
/*
这里的intent.resolveTypeIfNeeded返回这个intent的MIME类型,在这个例子中,
没有AndroidManifest.xml设置MainActivity的MIME类型,因此,这里返回null。
*/
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target, requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
Step 5. ActivityManagerProxy.startActivity
ActivityManagerNative.java (frameworks\base\core\java\android\app)
public int startActivity(......) throws RemoteException {
/*
参数resolvedType、resultWho均为null;
参数caller为ApplicationThread类型的Binder实体;
参数resultTo为一个Binder实体的远程接口,我们先不关注它;
参数grantedMode为0,我们也先不关注它;
参数requestCode为-1;
参数onlyIfNeeded和debug均空false。
*/
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
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);
return result;
}
Step 6. ActivityManagerService.startActivity
将操作转发给成员变量mStackSupervisor的startActivityMayWait函数,这里的mMainStack的类型为ActivityStackSupervisor。
@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("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
Step 7. ActivityStackSupervisor.startActivityMayWait
一、ActivityStackSupervisor.java (frameworks\base\services\core\java\com\android\server\am)
一)、startActivityMayWait函数的目标是启动com.dfp.test.TestActivity,假设系统之前没有启动过该Activity,
本例最终的结果将是:
1、由于在am中设置了FLAG_ACTIVITY_NEW_TASK标志,因此除了会创建一个新的ActivityRecord外,
还会新建一个TaskR额cord
2、还需要启动一个新的应用进程以加载并运行com.dfp.test.TestActivity的一个实例
3、如果TestActivity不是home,还需要停止当前正在显示的Activity
二)、将这个函数分三部分进行介绍
第一部分:
1、首先需要通过PKMS查询匹配该Intent的ActivityInfo
2、处理FLAG_CANT_SAVE_STATE的情况,但系统目前不支持此情况
3、获取调用者的pid和uid,由于本例的caller为null,故所得到的pid和uid均为am所在进程的uid和pid。
第二部分:启动核心函数startActivityLocked
第三部分:根据返回值做一些处理,那么res返回成功后(即res==IActivityManager.START_SUCCESS的时候)
后为何还需要等待? 这是因为目标Activity要运行在一个新的应用进程中,就必须等待那个应用进程正常启动
并处理相关的请求。
final int startActivityMayWait(......) {
// 第一部分:本例已经指明了component,这样可以省去为Intent匹配搜索之苦
boolean componentSpecified = intent.getComponent() != null;
// 创建一个新的Intent,防止客户传入的Intent被修改
intent = new Intent(intent);
// 查询满足条件的ActivityInfo,在resolveActivity内部和PKMS交互,
// 参数intent的内容进行解析,得到MainActivity的相关信息,保存在aInfo变量中
ActivityInfo aInfo =
resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
//
ActivityContainer container = (ActivityContainer) iContainer;
synchronized (mService) {
if (container != null && container.mParentActivity != null &&
container.mParentActivity.state != RESUMED) {
// Cannot start a child activity if the parent is not resumed.
return ActivityManager.START_CANCELED;
}
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
int callingPid;
if (callingUid >= 0) {
callingPid = -1;
} else if (caller == null) { //本例中,caller为null
callingPid = realCallingPid; // 取出调用进程的pid
callingUid = realCallingUid;// 取出调用进程的uid
} else {
callingPid = callingUid = -1;
}
final ActivityStack stack;
if (container == null || container.mStack.isOnHomeDisplay()) {
stack = mFocusedStack;
} else {
stack = container.mStack;
}
// 在本例中config为null
stack.mConfigWillChange = config != null && mService.mConfiguration.diff(config) != 0;
final long origId = Binder.clearCallingIdentity();
if (aInfo != null &&
(aInfo.applicationInfo.privateFlags
& ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
......
}
// 第二部分:调用此函数启动Activity,将返回值保存到res
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
Binder.restoreCallingIdentity(origId);
// 如果configuration发生变化,则调用AMS的updateConfigurationLocked进行处理
if (stack.mConfigWillChange) {
// If the caller also wants to switch to a new configuration,
// do so now. This allows a clean switch, as we are waiting
// for the current activity to pause (so we will not destroy
// it), and have not yet started the next activity.
mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
stack.mConfigWillChange = false;
mService.updateConfigurationLocked(config, null, false, false);
}
if (outResult != null) {
outResult.result = res; // 第三部分:设置启动结果
if (res == ActivityManager.START_SUCCESS) {
// 该结果在mWaitingActivityLaunched中保存
mWaitingActivityLaunched.add(outResult);
do {
try {
mService.wait(); // 等待启动结果
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
} else if (res == ActivityManager.START_TASK_TO_FRONT) { // 处理START_TASK_TO_FRONT结果
ActivityRecord r = stack.topRunningActivityLocked(null);
if (r.nowVisible && r.state == RESUMED) {
outResult.timeout = false;
outResult.who = new ComponentName(r.info.packageName, r.info.name);
outResult.totalTime = 0;
outResult.thisTime = 0;
} else {
outResult.thisTime = SystemClock.uptimeMillis();
mWaitingActivityVisible.add(outResult);
do {
try {
mService.wait();
} catch (InterruptedException e) {
}
} while (!outResult.timeout && outResult.who == null);
}
}
}
return res;
}
}
Step 8. ActivityStack.startActivityLocked
二、startActivityLocked分析
一)、startActivityLocked是startActivityMayWait第二阶段的重点
它的主要工作包括:
1、处理sourceRecord及resultRecord。其中,sourceRecord表示发起本次请求的Activity,
resultRecord表示接收处理结果的Activity(启动一个Activity肯定需要它完成某项事情,
当目标Activity将事情成后,就需要告知请求者该事情的处理结果)。
在一般情况下,sourceRecord和resultRecord应指向同一个Activity。
2、处理app switch。 如果AMS当前禁止app switch,则只能把本次启动请求保存起来,
以待允许app switch时在处理。 从代码中可知,AMS在处理本次请求前,会先调用
doPendingActivityLaunchesLocked函数,在该函数内部将启动之前因系统禁止app switch
而保存的Pending请求。
3、将对应ActivityRecord移动到Task的顶部
4、调用startActivityUncheckedLocked处理本次Activity启动请求
final int startActivityLocked(......) {
int err = ActivityManager.START_SUCCESS;
ProcessRecord callerApp = null;
// 如果caller不为空,则需要从AMS中找到它的ProcessRecord。本例中的caller为null
if (caller != null) {
// 从传进来的参数caller得到调用者的进程信息,并保存在callerApp变量中,这里就是Launcher应用程序的进程信息了
callerApp = mService.getRecordForAppLocked(caller);
// 其实就是想得到进程的pid和uid
if (callerApp != null) {
// 一定要保证调用进程的pid和uid正确
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else { // 如果用进程没有在AMS中注册,则认为其实非法的
err = ActivityManager.START_PERMISSION_DENIED;
}
}
final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
/*
下面两个变量很重要,sourceRecord用于描述启动目标Activity的那个Activity,
resultRecord用于描述接收启动的结果的Activity,即,该Activity的onActivityResult
将被调用已通知启动结果
*/
ActivityRecord sourceRecord = null;
ActivityRecord resultRecord = null;
if (resultTo != null) {
// 参数resultTo是Launcher这个Activity里面的一个Binder对象,通过它可以获得Launcher这个Activity的相关信息,保存在sourceRecord变量中。
sourceRecord = isInAnyStackLocked(resultTo);
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
// 获取Intent设置的启动标志,他们是和Launch Mode 类似的小把戏
final int launchFlags = intent.getFlags();
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
/*
前面介绍的Launch Mode和Acitivity的启动有关,实际上还有一部分标志用于控制Activity启动结果的通知。
使用FLAG_ACTIVITY_FORWARD_RESULT前Activity必须先存在(sourceRecord != null)
*/
}
// 检查err值及Intent的情况
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
// We couldn't find a class that can handle the given Intent.
// That's the end of that!
err = ActivityManager.START_INTENT_NOT_RESOLVED;
}
final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;
// 如果err不为0,则调用sendActivityResultLocked返回错误
if (err != ActivityManager.START_SUCCESS) {
if (resultRecord != null) { // resultRecord接收启动结果
resultStack.sendActivityResultLocked(-1,
resultRecord, resultWho, requestCode,
Activity.RESULT_CANCELED, null);
}
ActivityOptions.abort(options);
return err;
}
boolean abort = false;
// 权限检查
final int startAnyPerm = mService.checkPermission(
START_ANY_ACTIVITY, callingPid, callingUid);
abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
callingPid, resolvedType, aInfo.applicationInfo);
/* 可为AMS设置一个IActivityController类型的监听,AMS有任何动静都会回调该监听
不过谁又有如此本事监听AMS? 在进行Monkey测试的时候,Monkey会设置该回调的对象。
这样,Monkey就能根据AMS放映的情况进行相应的处理*/
if (mService.mController != null) {
try {
// The Intent we give to the watcher has the extra data
// stripped off, since it can contain private information.
Intent watchIntent = intent.cloneFilter();
abort |= !mService.mController.activityStarting(watchIntent,
aInfo.applicationInfo.packageName);
} catch (RemoteException e) {
mService.mController = null;
}
}
// 回调对象决定不启动该Activity,在进行monkey测试时,可设置黑名单,位于黑名单中的Activity将不能启动
if (abort) {
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
Activity.RESULT_CANCELED, null);
}
// We pretend to the caller that it was really started, but
// they will just get a cancel result.
ActivityOptions.abort(options);
// 通知resultRecord
return ActivityManager.START_SUCCESS;
}
// 创建一个ActivityRecord对象
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, this, container, options);
if (outActivity != null) {
outActivity[0] = r; // 保存到输入参数outActivity数组中
}
if (r.appTimeTracker == null && sourceRecord != null) {
// If the caller didn't specify an explicit time tracker, we want to continue
// tracking under any it has.
r.appTimeTracker = sourceRecord.appTimeTracker;
}
final ActivityStack stack = mFocusedStack;
// mResumedActivity 代表当前界面显示的Activity
if (voiceSession == null && (stack.mResumedActivity == null
|| stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
// 检查调用进程是否有权限切换Application
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
realCallingPid, realCallingUid, "Activity start")) {
// 如果调用进程没有权限切换Activity,则只能把这次Activity启动请求保存起来,
// 后续有机会再启动它
PendingActivityLaunch pal =
new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
// 所有Pending的请求均保存到AMS mPendingActivityLaunches变量中
mPendingActivityLaunches.add(pal);
ActivityOptions.abort(options);
return ActivityManager.START_SWITCHES_CANCELED;
}
}
if (mService.mDidAppSwitch) { // 用于控制app switch
// This is the second allowed switch since we stopped switches,
// so now just generally allow switches. Use case: user presses
// home (switches disabled, switch to home, mDidAppSwitch now true);
// user taps a home icon (coming from home so allowed, we hit here
// and now allow anyone to switch again).
mService.mAppSwitchesAllowedTime = 0;
} else {
mService.mDidAppSwitch = true;
}
doPendingActivityLaunchesLocked(false);
// 调用startActivityUncheckedLocked函数
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
if (err < 0) {
// If someone asked to have the keyguard dismissed on the next
// activity start, but we are not actually doing an activity
// switch... just dismiss the keyguard now, because we
// probably want to see whatever is behind it.
notifyActivityDrawnForKeyguard();
}
return err;
}
二)、先来看看app switch,它虽然是一个小变量,但是意义重大,关于resume/stopAppSwitches的介绍
AMS提供了两个函数,用于暂时,禁止App切换,为什么会有这种需求? 因为当某些重要(例如设置账号)
Activity处于前台(即用户当前所见的Activity)时,不希望系统因用户操作之外的原因而切换Activity(例如来电)。
@Override
public void stopAppSwitches() {
// 检查调用进程是否有STOP_APP_SWITCHES权限
if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.STOP_APP_SWITCHES);
}
synchronized (this) {
// 设置一个超时时间,过了这个时间,AMS可以重新切换App(switch app)
mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
+ APP_SWITCH_DELAY_TIME;
mDidAppSwitch = false; // 设置mDidAppSwitch为false
mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
// 防止应用进程调用了stop却没有调用resume,5秒后处理该消息
Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
}
}
以上代码中有两点需要注意:
1、此处控制机制名为app switch, 而不是activity switch。为什么? 因为从受保护的
Activity中启动另一个Activity,那么这个新Activity的目的应该是针对同一任务,
这次启动就不应该受app switch的制约了,反而应该对其打开绿灯。目前,
在执行Settings中设置设备策略(DevicePlicy)时就会stopAppSwitch。
2、执行stopAppSwitch后,应用程序应该调用resumeAppSwitches以允许app switch,
但是为了防止应用程序有意或无意忘记resume app switch,系统设置了一个超时时间(5s)
过了这个时间,系统将处理相应的消息,内部会resume app switch
三)、再看resumeAppSwitch函数
public void resumeAppSwitches() {
// 检测调用进程是否具有STOP_APP_SWITCHES权限
if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.STOP_APP_SWITCHES);
}
synchronized (this) {
// Note that we don't execute any pending app switches... we will
// let those wait until either the timeout, or the next start
// activity request.
mAppSwitchesAllowedTime = 0;
}
}
在resumeAppSwitches中只设置mAppSwitchesAllowTime的值为0,它并不处理在stop和resume这段时间内积攒起来的Pending请求,
那么这些请求时在何时被处理的?
1、从前面代码可知,如果在执行resume app switch后,又有新的请求需要处理,则先处理那些pending的请求
(调用doPendingActivityLaunchesLocked)。
2、在resumeAppSwitches中并未撤销stopAppSwitches函数中设置的超时消息,所以在处理那条超时消息,
所以在处理那条消息的过程中,也会处理pending的请求。
注: 在本例中,由于不考虑app switch的情况,那么接下来的工作就是调用startActivityUncheckLocked函数
来处理本次Activity的启动请求。此时,我们已经创建了一个ActivityRecord用于保存目标Acticity的相关信息
Step 9. ActivityStackSupervisor.startActivityUncheckedLocked
ActivityStackSupervisor.java (frameworks\base\services\core\java\com\android\server\am)
四)、startActivityUncheckLocked函数分析
startActivityUncheckLocked函数比较长,但目的比较简单,为新创建的ActivityRecord找到一个合适的Task。
本例最终结果就是创建一个新的Task,其中startActivityUncheckLocked函数比较复杂,分为三段进行分析
1、确定是否需要为新的Activity创建一个Task,即是否设置FLAG_ACTIVITY_NEW_TASK标志
2、找到一个合适的Task然后做一些处理
3、创建一个新的TaskRecord,并调用startAcitivityLocked函数进行处理
4、首先调用adjustStackFocus()判断目标Activity是否是普通APP还是Home,对应的Stack是否已经创建,若未创建,则创建对应Stack。然后根据启动的Flag和启动模式,判断是否需要在新的Task里运行目标Activity。若需要新的Task,则new 一个TaskRecord,若不需要,则获得当前Taskd的对象,并将TaskRecord和对应的ActivityRecord 关联起来。
final int startActivityUncheckedLocked(......) {
//
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;
// 函数首先获得intent的标志值,保存在launchFlags变量中。
int launchFlags = intent.getFlags();
// 判断是否需要调用本次Acivity启动而被系统移到后台的当前Activity的
// onUserLeaveHint 函数,
mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
// If the caller has asked not to resume at this point, we make note
// of this in the record so that we can skip it when trying to find
// the top running activity.
if (!doResume) {
r.delayedResume = true;
}
// 本例的notTop为空
ActivityRecord notTop =
(launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;
//
if (sourceRecord == null && inTask != null && inTask.stack != null) {
final Intent baseIntent = inTask.getBaseIntent();
final ActivityRecord root = inTask.getRootActivity();
if (baseIntent == null) {
ActivityOptions.abort(options);
throw new IllegalArgumentException("Launching into task without base intent: "
+ inTask);
}
// If this task is empty, then we are adding the first activity -- it
// determines the root, and must be launching as a NEW_TASK.
if (launchSingleInstance || launchSingleTask) {
if (!baseIntent.getComponent().equals(r.intent.getComponent())) {
ActivityOptions.abort(options);
throw new IllegalArgumentException("Trying to launch singleInstance/Task "
+ r + " into different task " + inTask);
}
if (root != null) {
ActivityOptions.abort(options);
throw new IllegalArgumentException("Caller with inTask " + inTask
+ " has root " + root + " but target is singleInstance/Task");
}
}
// If task is empty, then adopt the interesting intent launch flags in to the
// activity being started.
if (root == null) {
final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
| Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
launchFlags = (launchFlags & ~flagsOfInterest)
| (baseIntent.getFlags() & flagsOfInterest);
intent.setFlags(launchFlags);
inTask.setIntent(r);
addingToTask = true;
} else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
addingToTask = false;
} else {
addingToTask = true;
}
reuseTask = inTask;
} else {
inTask = null;
}
if (inTask == null) {
if (sourceRecord == null) {
// 如果请求的发起者为空,则需要新建一个Task
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0 && inTask == null) {
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
// 如果sourceRecord单独占一个Instance,则新的Activity必然处于另一个Task中
} else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
// 如果启动模式设置为singleTask或singleInstance,则也要创建Task
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
} else if (launchSingleInstance || launchSingleTask) {
// The activity being started is a single instance... it always
// gets launched into its own task.
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
}
}
ActivityInfo newTaskInfo = null;
Intent newTaskIntent = null;
ActivityStack sourceStack;
if (sourceRecord != null) {
if (sourceRecord.finishing) {
//
if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
newTaskInfo = sourceRecord.info;
newTaskIntent = sourceRecord.task.intent;
}
sourceRecord = null;
sourceStack = null;
} else {
sourceStack = sourceRecord.task.stack;
}
} else {
sourceStack = null;
}
boolean movedHome = false;
ActivityStack targetStack;
intent.setFlags(launchFlags);
final boolean noAnimation = (launchFlags & Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0;
// 这么多复杂的逻辑处理,无非就是要找到一个合适的Task,然后对应做一些处理。
//
if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
(launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
|| launchSingleInstance || launchSingleTask) {
}
// 第三阶段:
if (r.packageName != null) {
// 判断目标Activity是否已经在栈顶,如果是,需要判断是创建一个新的Activity还是调用
// onNewIntent(singleTop模式的处理)
ActivityStack topStack = mFocusedStack;
ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(notTop);
// 在本例中,需要创建一个Task
boolean newTask = false;
boolean keepCurTransition = false;
TaskRecord taskToAffiliate = launchTaskBehind && sourceRecord != null ?
sourceRecord.task : null;
// Should this be considered a new task?
if (r.resultTo == null && inTask == null && !addingToTask
&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
if (reuseTask == null) {
// 为该ActivityRecord设置一个新的TaskRecord
r.setTask(targetStack.createTaskRecord(getNextTaskId(),
newTaskInfo != null ? newTaskInfo : r.info,
newTaskIntent != null ? newTaskIntent : intent,
voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
taskToAffiliate);
} else {
r.setTask(reuseTask, taskToAffiliate);
}
if (isLockTaskModeViolation(r.task)) {
Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
if (!movedHome) {
if ((launchFlags &
(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity, so before starting
// their own activity we will bring home to the front.
r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
}
}
} else if (sourceRecord != null) {
final TaskRecord sourceTask = sourceRecord.task;
if (isLockTaskModeViolation(sourceTask)) {
Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
targetStack = sourceTask.stack;
targetStack.moveToFront("sourceStackToFront");
final TaskRecord topTask = targetStack.topTask();
if (topTask != sourceTask) {
targetStack.moveTaskToFrontLocked(sourceTask, noAnimation, options,
r.appTimeTracker, "sourceTaskToFront");
}
if (!addingToTask && (launchFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
// In this case, we are adding the activity to an existing
// task, but the caller has asked to clear that task if the
// activity is already running.
ActivityRecord top = sourceTask.performClearTaskLocked(r, launchFlags);
keepCurTransition = true;
if (top != null) {
ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
// For paranoia, make sure we have correctly
// resumed the top activity.
targetStack.mLastPausedActivity = null;
if (doResume) {
targetStack.resumeTopActivityLocked(null);
}
ActivityOptions.abort(options);
return ActivityManager.START_DELIVERED_TO_TOP;
}
} else if (!addingToTask &&
(launchFlags & Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) != 0) {
// In this case, we are launching an activity in our own task
// that may already be running somewhere in the history, and
// we want to shuffle it to the front of the stack if so.
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);
top.updateOptionsLocked(options);
top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
targetStack.mLastPausedActivity = null;
if (doResume) {
targetStack.resumeTopActivityLocked(null);
}
return ActivityManager.START_DELIVERED_TO_TOP;
}
}
// An existing activity is starting this new activity, so we want
// to keep the new one in the same task as the one that is starting
// it.
r.setTask(sourceTask, null);
} else if (inTask != null) {
// The caller is asking that the new activity be started in an explicit
// task it has provided to us.
if (isLockTaskModeViolation(inTask)) {
Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
targetStack = inTask.stack;
targetStack.moveTaskToFrontLocked(inTask, noAnimation, options, r.appTimeTracker,
"inTaskToFront");
// Check whether we should actually launch the new activity in to the task,
// or just reuse the current activity on top.
ActivityRecord top = inTask.getTopActivity();
if (top != null && top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
|| launchSingleTop || launchSingleTask) {
ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top, top.task);
if ((startFlags & ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
// We don't need to start a new activity, and
// the client said not to do anything if that
// is the case, so this is it!
return ActivityManager.START_RETURN_INTENT_TO_CALLER;
}
top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
return ActivityManager.START_DELIVERED_TO_TOP;
}
}
if (!addingToTask) {
// We don't actually want to have this activity added to the task, so just
// stop here but still tell the caller that we consumed the intent.
ActivityOptions.abort(options);
return ActivityManager.START_TASK_TO_FRONT;
}
r.setTask(inTask, null);
} else {
// This not being started from an existing activity, and not part
// of a new task... just put it in the top task, though these days
// this case should never happen.
targetStack = computeStackFocus(r, newTask);
targetStack.moveToFront("addingToTopTask");
ActivityRecord prev = targetStack.topActivity();
r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
r.info, intent, null, null, true), null);
mWindowManager.moveTaskToTop(r.task.taskId);
}
mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
intent, r.getUriPermissionsLocked(), r.userId);
if (sourceRecord != null && sourceRecord.isRecentsActivity()) {
r.task.setTaskToReturnTo(RECENTS_ACTIVITY_TYPE);
}
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.userId, r.task.taskId);
}
ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
targetStack.mLastPausedActivity = null;
// 调用startActivityLocked,此时ActivityRecord和TaskRecord均创建完毕
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, "startedActivity");
}
return ActivityManager.START_SUCCESS;
}
五)、以上代码第三阶段将创建一个新的TaskRecord,并调用startActivityLocked函数
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)) {
//
insertTaskAtTop(rTask, r);
mWindowManager.moveTaskToTop(taskId);
}
TaskRecord task = null;
if (!newTask) { // 如果不是新的Task,则从mHistory中找到对应的AcitivityRecord的位置
......
}
// 设置ActivityRecord的inHistory变量为true,表示已经加到mHistory数组中了
task = r.task;
task.addActivityToTop(r);
task.setFrontOfTask();
r.putInHistory();
// 最终调用resumeTopActivitiesLocked函数,后面我们重点分析这个函数
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
Step 10. ActivityStack.resumeTopActivityLocked
ActivityStack.java (frameworks\base\services\core\java\com\android\server\am)
六)、resumeTopActivitiesLocked函数分析
该函数首先判断栈顶是否有需要显示的Activity,没有则启动Launcher,如果有需要显示的,还需要判断是否有需要暂停的Activity,有则执行Activity暂停操作。
final boolean resumeTopActivityLocked(ActivityRecord prev) {
return resumeTopActivityLocked(prev, null);
}
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (mStackSupervisor.inResumeTopActivity) {
/// M: BMW. Add log @{
if (MultiWindowProxy.isSupported()) {
if (DEBUG_STACK) Slog.w(TAG, "[BMW] resumeTopActivityLocked:"
+ "Don't even start recursing Stack:" + this);
}
/// @}
// 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();
}
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
}
它首先看要启动的Activity是否就是当前处理Resumed状态的Activity,如果是的话,那就什么都不用做,直接返回就可以了;否则再看一 下系统当前是否休眠状态,如果是的话,再看看要启动的Activity是否就是当前处于堆栈顶端的Activity,如果是的话,也是什么都不用做。
上面两个条件都不满足,因此,在继续往下执行之前,首先要把当处于Resumed状态的Activity推入Paused状态,然后才可以启动新的 Activity。但是在将当前这个Resumed状态的Activity推入Paused状态之前,首先要看一下当前是否有Activity正在进入 Pausing状态,如果有的话,当前这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样就保证了所有需要进入 Paused状态的Activity串行处理。
这里没有处于Pausing状态的Activity,即mPausingActivity为null,而且mResumedActivity也不为 null,于是就调用startPausingLocked函数把Launcher推入Paused状态去了。
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
/*
1、从mHistory中找到第一个需要启动的ActivityRecord
2、函数先通过调用topRunningActivityLocked函数获得堆栈顶端的Activity,
这里就是MainActivity了,这是在上面的Step 9设置好的,保存在next变量中。
*/
final ActivityRecord next = topRunningActivityLocked(null);
/*
接下来把mUserLeaving的保存在本地变量userLeaving中,然后重新设置为false,
在上面的Step 9中,mUserLeaving的值为true,因此,这里的userLeaving为true。
*/
final boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
final TaskRecord prevTask = prev != null ? prev.task : null;
if (next == null) {
// There are no more activities!
final String reason = "noMoreActivities";
if (!mFullscreen) {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen.
final ActivityStack stack = getNextVisibleStackLocked();
if (adjustFocusToNextVisibleStackLocked(stack, reason)) {
return mStackSupervisor.resumeTopActivitiesLocked(stack, prev, null);
}
}
// Let's just start up the Launcher...
ActivityOptions.abort(options);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on home display
final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
}
// 本例中,next将是目标Activity
next.delayedResume = false;
// If the top activity is the resumed one, nothing to do.
if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Top activity resumed " + next);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
final TaskRecord nextTask = next.task;
if (prevTask != null && prevTask.stack == this &&
prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
if (prevTask == nextTask) {
prevTask.setFrontOfTask();
} else if (prevTask != topTask()) {
// This task is going away but it was supposed to return to the home stack.
// Now the task above it has to return to the home task instead.
final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
} else if (!isOnHomeDisplay()) {
return false;
} else if (!isHomeStack()) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Launching home next");
final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, "prevFinished");
}
}
/*
当我们处理休眠状态时,mLastPausedActivity保存堆栈顶端的Activity,因为当前不是休眠状态,所以mLastPausedActivity为null。
*/
if (mService.isSleepingOrShuttingDown()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Going to sleep and all paused");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
// Make sure that the user who owns this activity is started. If not,
// we will just leave it as is because someone should be bringing
// another user's activities to the top of the stack.
if (mService.mStartedUsers.get(next.userId) == null) {
Slog.w(TAG, "Skipping resume of top activity " + next
+ ": user " + next.userId + " is stopped");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
//将该ActivityRecord从下面几个队列中移除
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next);
// If we are currently pausing an activity, then don't do anything
// until that is done.
if (!mStackSupervisor.allPausedActivitiesComplete()) {
if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
"resumeTopActivityLocked: Skip resume: some activity pausing.");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
// Okay we are now going to start a switch, to 'next'. We may first
// have to pause the current activity, but this is an important point
// where we have decided to go to 'next' so keep track of that.
// XXX "App Redirected" dialog is getting too many false positives
// at this point, so turn off for now.
if (false) {
if (mLastStartedActivity != null && !mLastStartedActivity.finishing) {
long now = SystemClock.uptimeMillis();
final boolean inTime = mLastStartedActivity.startTime != 0
&& (mLastStartedActivity.startTime + START_WARN_TIME) >= now;
final int lastUid = mLastStartedActivity.info.applicationInfo.uid;
final int nextUid = next.info.applicationInfo.uid;
if (inTime && lastUid != nextUid
&& lastUid != next.launchedFromUid
&& mService.checkPermission(
android.Manifest.permission.STOP_APP_SWITCHES,
-1, next.launchedFromUid)
!= PackageManager.PERMISSION_GRANTED) {
mService.showLaunchWarningLocked(mLastStartedActivity, next);
} else {
next.startTime = now;
mLastStartedActivity = next;
}
} else {
next.startTime = SystemClock.uptimeMillis();
mLastStartedActivity = next;
}
}
mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
// We need to start pausing the current activity so the top one
// can be resumed...
boolean dontWaitForPause = (next.info.flags & ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
/*
1、如果当前正在中断一个Acitivity,需先等待那个Activity pause完毕,然后系统会重新
调用resumeTopActivityLocked函数以找到下一个个启动的Activity
2、mResumedActivity 指向上一次启动的Acitivity,也就是当前界面显示的这个Acitivity
在本例中,当前Activity就是Home界面
3、如果mResumedActivity为空,则一定是系统第一个启动的Acitivity,读者应该能猜出来他就是home
*/
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
// 先中断Home,这种情况放在最后进行分析
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
if (pausing) {
// At this point we want to put the upcoming activity's process
// at the top of the LRU list, since we know we will be needing it
// very soon and it would be a waste to let it get killed if it
// happens to be sitting towards the end.
if (next.app != null && next.app.thread != null) {
mService.updateLruProcessLocked(next.app, true, null);
}
return true;
}
// If the most recent activity was noHistory but was only stopped rather
// than stopped+finished because the device went to sleep, we need to make
// sure to finish it as we're making a new activity topmost.
if (mService.isSleeping() && mLastNoHistoryActivity != null &&
!mLastNoHistoryActivity.finishing) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"no-history finish of " + mLastNoHistoryActivity + " on new resume");
requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
null, "resume-no-history", false);
mLastNoHistoryActivity = null;
}
// 如果prev不为空,则需要通知WMS进行与Activity切换相关的工作
if (prev != null && prev != next) {
}
// 通知PKMS修改该package stop 状态
try {
AppGlobals.getPackageManager().setPackageStoppedState(
next.packageName, false, next.userId); /* TODO: Verify if correct userid */
} catch (RemoteException e1) {
}
// We are starting up the next activity, so tell the window manager
// that the previous one will be hidden soon. This way it can know
// to ignore it when computing the desired screen orientation.
if (prev != null) {
// 还是和wms有关,通知停止绘画
}
// 如果该ActivityRecord已有对应的进程存在,则需要重启Activity,就本例而言,
// 此进程还不存在,所以要先创建一个应用进程
if (next.app != null && next.app.thread != null && needResume) {
} else {
//第一次启动
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
// 通知wms显示启动界面
}
// 调用另外一个startSpecificActivityLocked函数
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
Step 11. ActivityStack.startPausingLocked
一、
1、当启动一个新Activity时,系统将先行处理当前的Activity,即调用startPausingLocked函数暂停当前Acitivity
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
if (mPausingActivity != null) {
if (!mService.isSleeping()) {
// Avoid recursion among check for sleep and complete pause during sleeping.
// Because activity will be paused immediately after resume, just let pause
// be completed by the order of activity paused from clients.
completePauseLocked(false);
}
}
// mResumedActivity 保存当前正现实的Activity
函数首先把mResumedActivity保存在本地变量prev中。在上一步Step 10中,说到mResumedActivity就是Launcher,因此,这里把Launcher进程中的ApplicationThread对象取出来,通过它来通知Launcher这个Activity它要进入Paused状态了。当然,这里的prev.app.thread是一个ApplicationThread对象的远程接口,通过调用这个远程接口的schedulePauseActivity来通知Launcher进入Paused状态。
ActivityRecord prev = mResumedActivity;
if (prev == null) {
if (!resuming) {
mStackSupervisor.resumeTopActivitiesLocked();
}
return false;
}
if (mActivityContainer.mParentActivity == null) {
// Top level stack, not a child. Look for child stacks.
mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping, resuming, dontWait);
}
// 设置mPausingActivity为当前Activity
mResumedActivity = null;
mPausingActivity = prev;
mLastPausedActivity = prev;
mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
prev.state = ActivityState.PAUSING; // 设置状态为PAUSING
prev.task.touchActiveTime();
clearLaunchTime(prev);
final ActivityRecord next = mStackSupervisor.topRunningActivityLocked();
if (mService.mHasRecents && (next == null || next.noDisplay || next.task != prev.task || uiSleeping)) {
/// M: Add for launch time enhancement @{
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF, "amScreenCapture");
if (!prev.isHomeActivity()) {
prev.updateThumbnailLocked(screenshotActivities(prev), null);
}
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER | Trace.TRACE_TAG_PERF);
/// @}
}
stopFullyDrawnTraceIfNeeded();
mService.updateCpuStats();
if (prev.app != null && prev.app.thread != null) {
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
// 调用当前Activity所在进程的schedulePauseActivity函数
参数prev.finishing表示prev所代表的Activity是否正在等待结束的Activity列表中,由于Laucher这个Activity还没结束,所以这里为false;参数prev.configChangeFlags表示哪些config发生了变化,这里我们不关心它的值。
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) { }
// 获取WakeLock,以防止在Activity切换过程中掉电
if (!uiSleeping && !mService.isSleepingOrShuttingDown()) {
mStackSupervisor.acquireLaunchWakelock();
}
if (mPausingActivity != null) {
// 暂停输入事件派发
if (!uiSleeping) {
prev.pauseKeyDispatchingLocked();
} else if (DEBUG_PAUSE) {
Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
}
if (dontWait) {
// If the caller said they don't want to wait for the pause, then complete
// the pause now.
completePauseLocked(false);
return false;
} else {
// 设置PAUSE超时,时间为500ms
Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
msg.obj = prev;
prev.pauseTime = SystemClock.uptimeMillis();
mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
return true;
}
} else {
if (!resuming) {
mStackSupervisor.getFocusedStack().resumeTopActivityLocked(null);
}
return false;
}
}
startPausingLocked将调用应用程序进程的schedulePauseActivity函数,并设置500ms的超时时间,所以应用进程需要尽快完成相关操作,和scheduleLaunchActivity一样,
schedulePauseActivity将向ActivityThread主线程发送PAUSE_ACTIVITY消息,最终该消息由handlePauseAcitivity来处理
二. Step 12 - Step 16:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;
Step 12. ApplicationThreadProxy.schedulePauseActivity
ApplicationThreadNative.java (frameworks\base\core\java\android\app)
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
data.writeInt(dontReport ? 1 : 0);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
这个函数通过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中。
Step 13. 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);
}
这里调用的函数SendMessage是ActivityThread类的成员函数。
上面说到,这里的finished值为false,因此,SendMessage的第一个参数值为H.PAUSE_ACTIVITY,表示要暂停token所代表的Activity,即Launcher。
Step 14. ActivityThread.SendMessage
ActivityThread.java (frameworks\base\core\java\android\app)
private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
这里首先将相关信息组装成一个msg,然后通过mH成员变量发送出去,mH的类型是H,继承于Handler类,是ActivityThread的内部类,因此,这个消息最后由H.handleMessage来处理。
Step 15. H.handleMessage
public void handleMessage(Message msg) {
switch (msg.what) {
case PAUSE_ACTIVITY:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&2) != 0);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
这里调用ActivityThread.handlePauseActivity进一步操作,msg.obj是一个ActivityRecord对象的引用,它代表的是Launcher这个Activity。
Step 16. ActivityThread.handlePauseActivity
2、ActivityThread.java (frameworks\base\core\java\android\app)
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
// 当Activity处于finishing状态时,finiished参数为true,不过在本例中该值为false
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
//调用Activity的onUserLeaving函数
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
// 调用Activity的onPause函数
performPauseActivity(token, finished, r.isPreHoneycomb());
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
if (!dontReport) {
try {
// 调用AMS的activityPaused函数
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
}
}
mSomeActivitiesChanged = true;
}
}
函数首先将Binder引用token转换成ActivityRecord的远程接口ActivityClientRecord,然后做了三个事情:1. 如果userLeaving为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity,用户要离开它了;2. 调用performPauseActivity函数来调用Activity.onPause函数,我们知道,在Activity的生命周期中,当它要让位于其它的Activity时,系统就会调用它的onPause函数;3. 它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService现在可以完成未竟的事情,即启动MainActivity了。
三. Step 17 - Step 24:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行;
Step 17. ActivityManagerProxy.activityPaused
ActivityManagerNative.java (frameworks\base\core\java\android\app)
public void activityPaused(IBinder token) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
这里通过Binder进程间通信机制就进入到ActivityManagerService.activityPaused函数中去了。
Step 18. ActivityManagerService.activityPaused
ActivityManagerService.java (frameworks\base\services\core\java\com\android\server\am)
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
这里,又再次进入到ActivityStack类中,执行activityPaused函数。
Step 19. ActivityStack.activityPausedLocked
ActivityStack.java (frameworks\base\services\core\java\com\android\server\am)
final void activityPausedLocked(IBinder token, boolean timeout) {
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
// 从消息队列中撤销PAUSE_TIMEOUT_MSG消息
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
// 完成本次pause操作
completePauseLocked(true);
} else {
// 设置ActivityRecotd状态
if (r.finishing && r.state == ActivityState.PAUSING) {
finishCurrentActivityLocked(r, FINISH_AFTER_VISIBLE, false);
}
}
/// M: activity state notifier @{
mService.notifyActivityState(r.packageName, r.getFocusAppPid(),
r.realActivity.getShortClassName(),
IActivityStateNotifier.ActivityState.Paused);
/// @}
}
}
这里通过参数token在mHistory列表中得到ActivityRecord,从上面我们知道,这个ActivityRecord代表的是 Launcher这个Activity,而我们在Step 11中,把Launcher这个Activity的信息保存在mPausingActivity中,因此,这里mPausingActivity等于r, 于是,执行completePauseLocked操作。
Step 20. ActivityStack.completePauseLocked
3、ActivityStack.java (frameworks\base\services\core\java\com\android\server\am)
最后通过resumeTopActivitiesLocked来启动目标Acitivity
private void completePauseLocked(boolean resumeNext) {
ActivityRecord prev = mPausingActivity;
if (prev != null) {
prev.state = ActivityState.PAUSED;
if (prev.finishing) {
prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false);
} else if (prev.app != null) {
if (prev.configDestroy) {
destroyActivityLocked(prev, true, "pause-config");
} else if (!hasVisibleBehindActivity() || mService.isSleepingOrShuttingDown()) {
// 将刚才被暂停的Activity保存到mStoppingActivities中
mStackSupervisor.mStoppingActivities.add(prev);
if (mStackSupervisor.mStoppingActivities.size() > 3 ||
prev.frontOfTask && mTaskHistory.size() <= 1) {
// 如果被暂停的Activity超过3个,则发送IDLE_NOW_MSG消息,该消息最终由我们前面介绍的activityIdleInternal处理
mStackSupervisor.scheduleIdleLocked();
} else {
mStackSupervisor.checkReadyForSleepLocked();
}
}
} else { // 设置mPausingActivity为null
prev = null;
}
// It is possible the activity was freezing the screen before it was paused.
// In that case go ahead and remove the freeze this activity has on the screen
// since it is no longer visible.
prev.stopFreezingScreenLocked(true /*force*/);
mPausingActivity = null;
}
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) { // resumeTopActivitiesLocked将启动目标activity
mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
} else {
}
}
}
函数首先把mPausingActivity变量清空,因为现在不需要它了,然后调用resumeTopActivityLokced进一步操作,它传入的参数即为代表Launcher这个Activity的ActivityRecord。
Step 21. ActivityStack.resumeTopActivityLokced
通过上面的Step 9,我们知道,当前在堆栈顶端的Activity为我们即将要启动的MainActivity,这里通过调用topRunningActivityLocked将它取回来,保存在next变量中。之前最后一个Resumed状态的Activity,即Launcher,到了这里已经处于Paused状态了,因此,mResumedActivity为null。最后一个处于Paused状态的Activity为Launcher,因此,这里的mLastPausedActivity就为Launcher。前面我们为MainActivity创建了ActivityRecord后,它的app域一直保持为null。有了这些信息后,上面这段代码就容易理解了,它最终调用startSpecificActivityLocked进行下一步操作。
Step 22. ActivityStackSupervisor.startSpecificActivityLocked
ActivityStackSupervisor.java (\frameworks\base\services\core\java\com\android\server\am)
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// 注意,这里由于是第一次启动应用程序的Activity,所以下面语句:
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
/*
取回来的app为null。在Activity应用程序中的AndroidManifest.xml配置文件中,
我们没有指定Application标签的process属性,系统就会默认使用package的名称,
这里就是"shy.luo.activity"了。每一个应用程序都有自己的uid,因此,这里uid + process的组合就
可以为每一个应用程序创建一个ProcessRecord。当然,我们可以配置两个应用程序具有相同的uid和package,
或者在AndroidManifest.xml配置文件的application标签或者activity标签中显式指定相同的process属性值,
这样,不同的应用程序也可以在同一个进程中启动。
*/
if (app != null && app.thread != null) {
try {
if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
Step 23. ActivityManagerService.startProcessLocked
final ProcessRecord startProcessLocked(......) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
......
String hostingNameStr = hostingName != null
? hostingName.flattenToShortString() : null;
if (app == null) {
checkTime(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
if (app == null) {
Slog.w(TAG, "Failed making new process record for "
+ processName + "/" + info.uid + " isolated=" + isolated);
return null;
}
app.crashHandler = crashHandler;
checkTime(startTime, "startProcess: done creating new process record");
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
checkTime(startTime, "startProcess: added package to existing proc");
}
......
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, "startProcess: done starting proc!");
return (app.pid != 0) ? app : null;
}
}
这里再次检查是否已经有以process + uid命名的进程存在,在我们这个情景中,返回值app为null,因此,后面会创建一个ProcessRecord,并存保存在成员变量mProcessNames中,最后,调用另一个startProcessLocked函数进一步操作:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
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.start接口来创建一个新的进程,新的进程会导入android.app.ActivityThread类,并且执行它的main函数,这就是为什么我们前面说每一个应用程序都有一个ActivityThread实例来对应的原因。
4、根据前面的介绍,此次目标Acitivity将走完onCreate、onStart和onResume流程,但是被暂停的Activity才刚走完onPause流程,那么什么时候调用onStop?
答案就在activityIdelInternal中,他将成为mStopingActivities中的成员调用stopActivityLocked函数
final void stopActivityLocked(ActivityRecord r) {
if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
|| (r.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0) {
if (!r.finishing) {
if (!mService.isSleeping()) {
if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
"stop-no-history", false)) {
// Activity was finished, no need to continue trying to schedule stop.
adjustFocusedActivityLocked(r, "stopActivityFinished");
r.resumeKeyDispatchingLocked();
return;
}
} else {
}
}
}
if (r.app != null && r.app.thread != null) {
adjustFocusedActivityLocked(r, "stopActivity");
r.resumeKeyDispatchingLocked();
try {
r.stopped = false;
// 设置STOPPING状态,并调用对应的scheduleStopActivity函数
r.state = ActivityState.STOPPING;
r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
if (mService.isSleepingOrShuttingDown()) {
r.setSleeping(true);
}
Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
} catch (Exception e) {
}
}
}
5、对应进程scheduleStopActivity函数将根据visible的情况,向主线程消息循环发送H.STOP_ACTIVITY_HIDE和 H.STOP_ACTIVITY_SHOW 消息。
不论哪种情况,最终都由handleStopActivity来处理。
private void handleStopActivity(IBinder token, boolean show, int configChanges) {
ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
StopInfo info = new StopInfo();
// 调用Activity的onStop函数
performStopActivityInner(r, info, show, true);
updateVisibility(r, show);
info.activity = r;
info.state = r.state;
info.persistentState = r.persistentState;
mH.post(info);
mSomeActivitiesChanged = true;
}
Step 24. ActivityThread.main
一、应用进程创建及初始化
1、ActivityThread.java (frameworks\base\core\java\android\app)
public static void main(String[] args) {
logAppLaunchTime(TAG, "ActivityThread is created"); /// M: It's for debugging App Launch time
SamplingProfilerIntegration.start();
// 和调试及strictMode有关
CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
AndroidKeyStoreProvider.install();
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
// 设置进程名为"<pre-initialized>"
Process.setArgV0("<pre-initialized>");
// 准备主线程消息循环
Looper.prepareMainLooper();
// 创建一个ActivityThread对象
ActivityThread thread = new ActivityThread();
// 调用attach函数,注意其参数数值false
thread.attach(false);
Looper.loop(); // 进入主线程消息循环
}
在main函数中内部将创建一个消息循环Loop,接着调用ActivityThread的attach函数,最终将主线程加入消息循环。
2、我们在分析AMS的setSystemProcess是曾分析过ActivityThread的attach函数,那时传入的参数值为true,现在看看设置为false的情况
ActivityThread.java (frameworks\base\core\java\android\app)
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
// 设置在DDMS中看到的本进程的名字为"<pre-initialized>"
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
// 设置RuntimeInit的mApplicationObject参数,后续会介绍RuntimeInit类
RuntimeInit.setApplicationObject(mAppThread.asBinder());
// 获取和AMS交互的Binder客户端
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
// 调用AMS的attachApplication,mAppThread为ApplicationThread类型,它是应用进程和AMS交互的接口
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable() {
@Override
public void run() {
if (!mSomeActivitiesChanged) {
return;
}
Runtime runtime = Runtime.getRuntime();
long dalvikMax = runtime.maxMemory();
long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
if (dalvikUsed > ((3 * dalvikMax) / 4)) {
if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax / 1024)
+ " total=" + (runtime.totalMemory() / 1024)
+ " used=" + (dalvikUsed / 1024));
mSomeActivitiesChanged = false;
try {
mgr.releaseSomeActivities(mAppThread);
} catch (RemoteException e) {
}
}
}
});
} else {// system process处理
}
}
这个函数在进程中创建一个ActivityThread实例,然后调用它的attach函数,接着就进入消息循环了,直到最后进程退出。
函数attach最终调用了ActivityManagerService的远程接口ActivityManagerProxy的attachApplication函数,传入的参数是mAppThread,这是一个ApplicationThread类型的Binder对象,它的作用是用来进行进程间通信的。
四. Step 25 - Step 27:ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;
Step 25. ActivityManagerProxy.attachApplication
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();
}
这里通过Binder驱动程序,最后进入ActivityManagerService的attachApplication函数中。
Step 26. ActivityManagerService.attachApplication
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
// 这里将操作转发给attachApplicationLocked函数。
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
Step 27. ActivityManagerService.attachApplicationLocked
3、我们知道,AMS创建一个应用进程后,会设置一个超时时间(一般是10秒),如果超过这个时间,应用进程汗没有和AMS交互,则断定该进程创建失败。
所以,应用进程启动后,需要尽快和AMS交互,及调用AMS的attachApplication函数。在该函数内部将调用attachApplicationLocked,所以此处直接分析attachApplicationLocked,
先看其第一阶段工作。
第一阶段工作比较简单:
1)设置代表该应用进程ProcessRecord对象的一些成员变量,如用于和应用进程交互的thread对象、进程调度优先级及oom_adj的值等。
2)从消息队列中撤销PROC_START_TIMEOUT_MSG.
至此,该阶段启动成功,但是这一阶段的工作仅针对进程本身(如设置调度优先级,oom_adj等),还没有涉及和Activity启动相关的内容,这部分工作将在第二阶段完成。
第二阶段: 工作主要是为调用Application的bindApplication做准备
/*正如我们在前面分析时提到的,刚创建的这个进程并不知道自己的历史使命是什么,甚至连自己的进程名都不知道,只能设为<pre-initiallzed>。其实,Android应用进程的历史使命是
AMS在其启动后才赋予它的,这一点和我们理解的一般意义上的进程不太一样。根据之前的介绍,Andorid的组件应该运行在Anroid运行环境中。从OS角度来说,该运行环境需要和一个进程
绑定。所以,创建应用进程这一步只是创建一个能运行Android运行环境的容器,bindApplication的功能就是创建并初始化位于该进程的Anroid运行环境*/
public final void bindApplication()
第三阶段:通知应用进程Activity和Service等组件,其中用于启动Activity的函数是ActivityStack realStartActivityLocked
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) { // 第一阶段 此pid代表调用进程pid
ProcessRecord app;
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid); // 根据pid查找对应的ProcessRecord对象
}
} else {
app = null;
}
/*如果该应用进程由AMS启动,则它一定在AMS中有对应的ProcessRecord,读者可以回顾前面创建
应用进程的代码:AMS先创建了一个ProcessRecord对象,然后才发命令给Zygote。
如果此处app为null,则表示AMS没有该进程的记录,故需要“杀死”它
* */
if (app == null) {
EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
if (pid > 0 && pid != MY_PID) { // 如果pid大于零,且不是system_server进程,则“杀死”process
Process.killProcessQuiet(pid);
//TODO: killProcessGroup(app.info.uid, pid);
} else {
try { // 调用ApplicationThread的scheduleExit函数,应用进程完成处理工作后,将退出运行
thread.scheduleExit();
} catch (Exception e) {
// Ignore exceptions.
}
}
return false;
}
/*
判断app的Thread是否为空,如果不为空,则表示该ProcessRecord对象还未和一个应用进程绑定。
注意,app是根据pid查找到的,如果旧的进程没有被“杀死”,则系统不会重用该pid
*/
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
final String processName = app.processName;
try {
/*
创建一个应用进程“讣告”接受对象。当应用进程退出时,该对象的binderDied将被调用。
这样,AMS就能做相应处理。binderDied函数将在另外一个线程中执行,其内部也会调用
handleAppDiedLocked。假如用户在binderDied被调用之前又启动一个进程,
那么就会出现以上代码中app.thread不为null的情况。这是多线程环境中常出现的情况
*/
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}
// 设置该进程的调度优先级和oom_adj相关的成员
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;
// 启动成功,从消息队列中撤销PROC_START_TIMEOUT_MSG消息
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
// 第二阶段 systemserver 早就启动完毕,所以normalMode为true
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
// 该函数内部将查询(根据进程名,uid确定)PKMS以获取需要运行在该进程中的ContentProvider
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
try {
int testMode = IApplicationThread.DEBUG_OFF;
if (mDebugApp != null && mDebugApp.equals(processName)) {
// 处理debug选项
testMode = mWaitForDebugger
? IApplicationThread.DEBUG_WAIT
: IApplicationThread.DEBUG_ON;
app.debugging = true;
if (mDebugTransient) {
mDebugApp = mOrigDebugApp;
mWaitForDebugger = mOrigWaitForDebugger;
}
}
// 处理profile
String profileFile = app.instrumentationProfileFile;
ParcelFileDescriptor profileFd = null;
int samplingInterval = 0;
boolean profileAutoStop = false;
if (mProfileApp != null && mProfileApp.equals(processName)) {
mProfileProc = app;
profileFile = mProfileFile;
profileFd = mProfileFd;
samplingInterval = mSamplingInterval;
profileAutoStop = mAutoStopProfiler;
}
boolean enableOpenGlTrace = false;
if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
enableOpenGlTrace = true;
mOpenGlTraceApp = null;
}
// If the app is being launched for restore or full backup, set it up specially
boolean isRestrictedBackupMode = false;
if (mBackupTarget != null && mBackupAppName.equals(processName)) {
isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
|| (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
|| (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
}
// dex化对应的apk包
ensurePackageDexOpt(app.instrumentationInfo != null
? app.instrumentationInfo.packageName
: app.info.packageName);
// 如果设置了设置了Instrumentation类,该类所在的package也需要dex化
if (app.instrumentationClass != null) {
ensurePackageDexOpt(app.instrumentationClass.getPackageName());
}
ApplicationInfo appInfo = app.instrumentationInfo != null
? app.instrumentationInfo : app.info;
// 查询该Application使用的CompatibilityInfo
app.compat = compatibilityInfoForPackageLocked(appInfo);
if (profileFd != null) { // 用于记录性能文件
profileFd = profileFd.dup();
}
ProfilerInfo profilerInfo = profileFile == null ? null
: new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
// 通过ApplicationThread和应用进程交互,调用其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());
//
updateLruProcessLocked(app, false, null);
// 记录两个时间
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
} catch (Exception e) {
app.resetPackageList(mProcessStats);
app.unlinkDeathRecipient();
startProcessLocked(app, "bind fail", processName);
return false;
}
// 从mPersistentStartingProcesses和mProcessesOnHold中删除相关信息
mPersistentStartingProcesses.remove(app);
mProcessesOnHold.remove(app);
boolean badApp = false;
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
badApp = true;
}
}
// Find any services that should be running in this process...
if (!badApp) {
try {
didSomething |= mServices.attachApplicationLocked(app, processName);
} catch (Exception e) {
badApp = true;
}
}
// Check if a next-broadcast receiver is in this process...
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
try {
didSomething |= sendPendingBroadcastsLocked(app);
} catch (Exception e) {
badApp = true;
}
}
// Check whether the next backup agent is in this process...
if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
try {
thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
mBackupTarget.backupMode);
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
badApp = true;
}
}
if (badApp) {
/*
如果以上一个组件启动错误,则设置badApp为true。此处将调用handleAppDiedLocked进行处理
*/
app.kill("error during init", true);
handleAppDiedLocked(app, false, true);
return false;
}
/*
调整进程oom_adj值,didsomething表示在以上流程中是否启动了Activity或其他组件。
如果启动了任一组件,则didsomething为true,读者以后知道,这里的启动只是向应用进程发出对应的指令,
客户端进程是否成功处理还是未知数。基于这种考虑,此处不宜马上调节进程的oom_adj.
读者可简单的把oom_adj看做一种优先级。如果一个应用进程没有运作任何组件,那么当内存出现不足时,
该进程是最先被系统“杀死”的。反之,如果一个应用进程运行的组建越多,那么它就越不易被系统“杀死”
以回收内存。updateOomAdjLocked就是根据该进程中的组件的情况对应调节进程的oom_adj值
*/
if (!didSomething) {
updateOomAdjLocked();
}
return true;
}
4、bindApplication为应用程序绑定一个Application
ActivityThread.java (frameworks\base\core\java\android\app)
public final void bindApplication(......) {
if (services != null) { // 保存AMS传递过来的系统service信息
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
// 向主线程消息队列添加SET_CORE_SETTINGS消息
setCoreSettings(coreSettings);
IPackageManager pm = getPackageManager();
android.content.pm.PackageInfo pi = null;
try {
pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());
} catch (RemoteException e) {
}
if (pi != null) {
boolean sharedUserIdSet = (pi.sharedUserId != null);
boolean processNameNotDefault =
(pi.applicationInfo != null &&
!appInfo.packageName.equals(pi.applicationInfo.processName));
boolean sharable = (sharedUserIdSet || processNameNotDefault);
// Tell the VMRuntime about the application, unless it is shared
// inside a process.
if (!sharable) {
VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,
appInfo.processName);
}
}
// 创建AppBindData对象,用于保存一些参数
AppBindData data = new AppBindData();
data.processName = processName;
data.appInfo = appInfo;
data.providers = providers;
data.instrumentationName = instrumentationName;
data.instrumentationArgs = instrumentationArgs;
data.instrumentationWatcher = instrumentationWatcher;
data.instrumentationUiAutomationConnection = instrumentationUiConnection;
data.debugMode = debugMode;
data.enableOpenGlTrace = enableOpenGlTrace;
data.restrictedBackupMode = isRestrictedBackupMode;
data.persistent = persistent;
data.config = config;
data.compatInfo = compatInfo;
data.initProfilerInfo = profilerInfo;
sendMessage(H.BIND_APPLICATION, data);
}
5、有以上代码可知,ApplicationThread接收到来之AMS的指令后,会将指令中的参数封装到一个数据结构中,然后通过发送消息的方式转交给主线程去处理。
BIND_APPLICATION最终将由handleBindApplication函数处理。该函数并不复杂,但是其中有些点是值得关注的,这些点主要是初始化应用进程的一些参数。
其中最主要的有两点:
1)创建一个Application对象,该对象是本进程中运行的第一个Application
2)如果该进程Application有ContentProvider,则应安装他们
3)ContentProvider的创建于bindApplication函数中,其时机早于其他组建的创建
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
// 初始化性能统计对象
mProfiler = new Profiler();
if (data.initProfilerInfo != null) {
mProfiler.profileFile = data.initProfilerInfo.profileFile;
mProfiler.profileFd = data.initProfilerInfo.profileFd;
mProfiler.samplingInterval = data.initProfilerInfo.samplingInterval;
mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler;
}
logAppLaunchTime(TAG, "handleBindApplication is called"); /// M: It's for debugging App Launch time
// 设置进程名,从此,之前那个名为“<pre_initialized>”的进程终于有了正式的名字
Process.setArgV0(data.processName);
android.ddm.DdmHandleAppName.setAppName(data.processName,
UserHandle.myUserId());
// 启动性能统计
if (mProfiler.profileFd != null) {
mProfiler.startProfiling();
}
// 如果目标SDK版本小于12,则设置AsyncTask使用pool executor,否则使用
// serialized executor。这些executor涉及java concurrent 类
if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
/*设置时间
*/
TimeZone.setDefault(null);
/*
* 设置语言
*/
Locale.setDefault(data.config.locale);
/*设置资源及兼容模式
*/
mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo);
mCurDefaultDisplayDpi = data.config.densityDpi;
applyCompatConfiguration(mCurDefaultDisplayDpi);
// 根据传递过来的ApplicationInfo创建一个对应的LoadApk对象
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
/**
* 对于系统APK,如果当前系统为userdebug/eng版,则需要使能dropbox的日志记录
*/
if ((data.appInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
== 0) {
mDensityCompatMode = true;
Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
}
updateDefaultDensity();
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
if (!Process.isIsolated()) {
final File cacheDir = appContext.getCacheDir();
if (cacheDir != null) {
// Provide a usable directory for temporary files
System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
} else {
Log.v(TAG, "Unable to initialize \"java.io.tmpdir\" property due to missing cache directory");
}
// Use codeCacheDir to store generated/compiled graphics code
final File codeCacheDir = appContext.getCodeCacheDir();
if (codeCacheDir != null) {
setupGraphicsSupport(data.info, codeCacheDir);
} else {
Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
}
}
final boolean is24Hr = "24".equals(mCoreSettings.getString(Settings.System.TIME_12_24));
DateFormat.set24HourTimePref(is24Hr);
View.mDebugViewAttributes =
mCoreSettings.getInt(Settings.Global.DEBUG_VIEW_ATTRIBUTES, 0) != 0;
/**
* For system applications on userdebug/eng builds, log stack
* traces of disk and network access to dropbox for analysis.
*/
if ((data.appInfo.flags &
(ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
StrictMode.conditionallyEnableDebugLogging();
}
/**
* Initialize the default http proxy in this process for the reasons we set the time zone.
*/
IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
if (b != null) {
// In pre-boot mode (doing initial launch to collect password), not
// all system is up. This includes the connectivity service, so don't
// crash if we can't get it.
IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
try { // 设置HTTP代理消息
final ProxyInfo proxyInfo = service.getProxyForNetwork(null);
Proxy.setHttpProxySystemProperty(proxyInfo);
} catch (RemoteException e) {
}
}
if (data.instrumentationName != null) {
// 在正常情况下此条件不满足
} else {
// 创建Instrumentation对象,在正常情况下都在这个条件下执行
mInstrumentation = new Instrumentation();
}
// 如果package中声明了FLAG_LARGE_HEAP,则可跳过虚拟机的内存限制,放心使用内存
if ((data.appInfo.flags & ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
} else {
// Small heap, clamp to the current growth limit and let the heap release
// pages after the growth limit to the non growth limit capacity. b/18387825
dalvik.system.VMRuntime.getRuntime().clampGrowthLimit();
}
// Allow disk access during application and provider setup. This could
// block processing ordered broadcasts, but later processing would
// probably end up doing the same disk access.
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
try {
//创建一个Application,data.info为LoadedApk类型,在其内部会通过Java反射机制
// 创建一个在该APK AndroidManifest.xml中声明的Application对象
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
// mInitialApplication保存该进程中第一个创建的Application
mInitialApplication = app;
// 安装package中携带的contentprovider
if (!data.restrictedBackupMode) {
List<ProviderInfo> providers = data.providers;
if (providers != null) {
installContentProviders(app, providers);
// For process that contains content providers, we want to
// ensure that the JIT is enabled "at some point".
mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10 * 1000);
}
}
// Do this after providers, since instrumentation tests generally start their
// test thread at this point, and we don't want that racing.
try {
mInstrumentation.onCreate(data.instrumentationArgs);
} catch (Exception e) {
throw new RuntimeException(
"Exception thrown in onCreate() of "
+ data.instrumentationName + ": " + e.toString(), e);
}
try { // 调用Application的onCraeate函数,做一些初始化工作
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
五. Step 28 - Step 35:ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。
Step 28. ActivityStack.realStartActivityLocked
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
......
// r,是一个ActivityRecord类型的Binder对象,用来作来这个Activity的token值。
r.app = app;
......
int idx = app.activities.indexOf(r);
if (idx < 0) {
app.activities.add(r);
}
.....
try {
if (app.thread == null) {
throw new RemoteException();
}
List<ResultInfo> results = null;
List<ReferrerIntent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
}
// app.thread进入到ApplicationThreadProxy的scheduleLaunchActivity函数中
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);
......
} catch (RemoteException e) {
}
......
return true;
}
二、ActivityStack realStartActivityLocked 分析
AMS调用完bindApplication后,将通过realStartActivityLocked启动Activity。在此之前,要创建完应用进程并初始化Android运行环境
6.0的代码中已经没有该方法,但是里面包含了两个关键函数,分别是:scheduleLaunchActivity和completeResumeLocked。其中,
scheduleLaunchActivity用于和应用进程交互,通知它启动目标Activity。而completeResumeLocked将继续AMS的处理流程。
Step 29. ApplicationThreadProxy.scheduleLaunchActivity
public final void scheduleLaunchActivity(......) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
intent.writeToParcel(data, 0);
data.writeStrongBinder(token);
data.writeInt(ident);
info.writeToParcel(data, 0);
curConfig.writeToParcel(data, 0);
if (overrideConfig != null) {
data.writeInt(1);
overrideConfig.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
compatInfo.writeToParcel(data, 0);
data.writeString(referrer);
data.writeStrongBinder(voiceInteractor != null ? voiceInteractor.asBinder() : null);
data.writeInt(procState);
data.writeBundle(state);
data.writePersistableBundle(persistentState);
data.writeTypedList(pendingResults);
data.writeTypedList(pendingNewIntents);
data.writeInt(notResumed ? 1 : 0);
data.writeInt(isForward ? 1 : 0);
if (profilerInfo != null) {
data.writeInt(1);
profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
data.writeInt(0);
}
mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
这个函数最终通过Binder驱动程序进入到ApplicationThread的scheduleLaunchActivity函数中。
Step 30. ActivityThread.scheduleLaunchActivity
1、ActivityThread.java (frameworks\base\core\java\android\app)
public final void scheduleLaunchActivity(......) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
...... // 保存AMS发送过来的参数信息
// 向主线程发送消息,该消息的处理在handleLaunchActivity中进行
sendMessage(H.LAUNCH_ACTIVITY, r);
}
Step 31. ActivityThread.SendMessage
2、frameworks/base/core/java/android/app/ActivityThread.java
public void handleMessage(Message msg) {
switch (msg.what) {
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
// 根据ApplicationInfo得到对应的PakcageInfo
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
// 调用handleLaunchActivity处理
handleLaunchActivity(r, null);
} break;
Step 32. H.handleMessage
Step 33. ActivityThread.handleLaunchActivity
Step 34. ActivityThread.performLaunchActivity
Step 35. MainActivity.onCreate
整个应用程序的启动过程要执行很多步骤,但是整体来看,主要分为以下五个阶段:
一. Step1 - Step 11:Launcher通过Binder进程间通信机制通知ActivityManagerService,它要启动一个Activity;
二. Step 12 - Step 16:ActivityManagerService通过Binder进程间通信机制通知Launcher进入Paused状态;
三. Step 17 - Step 24:Launcher通过Binder进程间通信机制通知ActivityManagerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行;
四. Step 25 - Step 27:ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信;
五. Step 28 - Step 35:ActivityManagerService通过Binder进程间通信机制通知ActivityThread,现在一切准备就绪,它可以真正执行Activity的启动操作了。
这样,应用程序的启动过程就介绍完了,它实质上是启动应用程序的默认Activity,