在進(jìn)階Android的路上,了解理解一個(gè)應(yīng)用根Activity啟動(dòng)流程可以作為一個(gè)切入點(diǎn),由此展開(kāi)進(jìn)階之路。平時(shí)我們開(kāi)發(fā)的應(yīng)用都是展示在Android系統(tǒng)桌面上,這個(gè)系統(tǒng)桌面其實(shí)也是一個(gè)Android應(yīng)用,它叫Launcher。所以本文通過(guò)源碼層面從Launcher調(diào)用ATMS,ATMS調(diào)用ApplicationThread,最后ActivityThread啟動(dòng)Activity三個(gè)過(guò)程了解Activity啟動(dòng)流程(文中源碼基于Android 10 )。
首先來(lái)個(gè)腦圖,對(duì)于整體模塊在大腦中形成一個(gè)整體印象
Launcher到ActivityTaskManagerService
Launcher 調(diào)用 Activity
- 至于Launcher如何加載展示應(yīng)用程序到界面這里先略過(guò)(與PMS相關(guān)),本文先關(guān)注Activity啟動(dòng)過(guò)程。當(dāng)我們點(diǎn)擊系統(tǒng)桌面的應(yīng)用圖標(biāo),直接響應(yīng)的則是Launcher這個(gè)應(yīng)用程序,會(huì)調(diào)用它的startActivitySafely方法
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
public boolean startActivitySafely(View v, Intent intent, ItemInfo item,
@Nullable String sourceContainer) {
.....
boolean success = super.startActivitySafely(v, intent, item, sourceContainer); // 1
if (success && v instanceof BubbleTextView) {
// This is set to the view that launched the activity that navigated the user away
// from launcher. Since there is no callback for when the activity has finished
// launching, enable the press state and keep this reference to reset the press
// state when we return to launcher.
BubbleTextView btv = (BubbleTextView) v;
btv.setStayPressed(true);
addOnResumeCallback(btv);
}
return success;
}
- 通過(guò)以上源碼,在注釋1調(diào)用的是父類的startActivitySafely方法,Launcher類本身就是Activity,它的父類為BaseDraggingActivity,接著看到它的startActivitySafely方法
packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.java
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
@Nullable String sourceContainer) {
.......
// Prepare intent
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //1
if (v != null) {
intent.setSourceBounds(getViewBounds(v));
}
try {
......
if (isShortcut) {
// Shortcuts need some special checks due to legacy reasons.
startShortcutIntentSafely(intent, optsBundle, item, sourceContainer);
} else if (user == null || user.equals(Process.myUserHandle())) {
// Could be launching some bookkeeping activity
startActivity(intent, optsBundle);//2
AppLaunchTracker.INSTANCE.get(this).onStartApp(intent.getComponent(),
Process.myUserHandle(), sourceContainer);
} else {
.......
}
getUserEventDispatcher().logAppLaunch(v, intent);
getStatsLogManager().logAppLaunch(v, intent);
return true;
} catch (NullPointerException|ActivityNotFoundException|SecurityException e) {
Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
}
return false;
}
- 以上源碼看到注釋1,設(shè)置啟動(dòng)Activity的Flag為FLAG_ACTIVITY_NEW_TASK,設(shè)置這個(gè)Flag則Activity的啟動(dòng)就會(huì)在新的任務(wù)棧中啟動(dòng),后面還會(huì)遇到它;接著看到注釋2,調(diào)用了startActivity的方法,顯然這就是調(diào)用了Activity類的startActivity方法。繼續(xù)探究Activity類的startActivity方法
frameworks/base/core/java/android/app/Activity.java
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);//1
} else {
// Note we want to go through this call for compatibility with
// applications that may have overridden the method.
startActivityForResult(intent, -1);
}
}
- 有以上源碼看到注釋1,Activity類的startActivity方法調(diào)用的是startActivityForResult方法,這個(gè)方法日常開(kāi)發(fā)啟動(dòng)Activity有參數(shù)回調(diào)也會(huì)使用,這里參數(shù)傳入-1,表明Launcher啟動(dòng)Activity并不管它成功與否。接著看startActivityForResult方法
frameworks/base/core/java/android/app/Activity.java
Activity mParent;
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) { //1
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);//2
......
} else {
......
}
}
- 通過(guò)以上源碼看到注釋1,mParent的聲明類型為Activity,當(dāng)前還是正在起Activity,mParent == null成立,看到注釋2調(diào)用了Instrumentation類的execStartActivity方法,Instrumentation允許您監(jiān)視系統(tǒng)與應(yīng)用程序之間的所有交互(Instrumentation注釋:allowing you to monitor all of the interaction the system has with the application.),接著看到它的execStartActivity方法
Instrumentation 調(diào)用到ATMS
frameworks/base/core/java/android/app/Instrumentation.java
@UnsupportedAppUsage
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;//1
......
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
int result = ActivityTaskManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options); //2
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
- 通過(guò)以上源碼看到注釋1,這里獲取了IApplicationThread,如果你了解Binder,第一反應(yīng)就應(yīng)該很清晰,目前處于Launcher應(yīng)用程序進(jìn)程,要啟動(dòng)Activity則需要請(qǐng)求系統(tǒng)服務(wù)進(jìn)程(SystemServer),而Android進(jìn)程間通信則可以使用Binder,而這里實(shí)現(xiàn)方式為AIDL,它的實(shí)現(xiàn)類為ActivityThread的內(nèi)部類ApplicationThread,而ApplicationThread作用則為應(yīng)用程序進(jìn)程和系統(tǒng)服務(wù)進(jìn)程通信的橋梁,后面還會(huì)繼續(xù)提到;接著看到注釋2,這里調(diào)用ActivityTaskManager.getService則可以獲取ActivityTaskManagerService的代理對(duì)象,看看他的實(shí)現(xiàn)
frameworks/base/core/java/android/app/ActivityTaskManager.java
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);//1
return IActivityTaskManager.Stub.asInterface(b); //2
}
};
由以上源碼注釋1,通過(guò)ServiceManager來(lái)獲取遠(yuǎn)程服務(wù)ActivityTaskManagerService,ServiceManager底層最終調(diào)用的還是c++層的ServiceManager,它是Binder的守護(hù)服務(wù),通過(guò)它能夠獲取在Android系統(tǒng)啟動(dòng)時(shí)注冊(cè)的系統(tǒng)服務(wù),這其中就包含這里提到的ATMS;接著回到注釋2建立 Launcher與 ATMS的連接,這樣回到execStartActivity方法,Launcher就通過(guò)調(diào)用ATMS的startActivity方法將啟動(dòng)Activity的數(shù)據(jù)交給ATMS服務(wù)來(lái)處理了。
-
為了更好理解,看看Launcher調(diào)用到ActivityTaskManagerService時(shí)序圖來(lái)對(duì)上面的步驟進(jìn)行回顧
Launcher調(diào)用到ActivityTaskManagerService時(shí)序圖.jpg
ActivityTaskManagerService 調(diào)用ApplicationThread
ATMS處理啟動(dòng)Activity請(qǐng)求
- 通過(guò)上一小節(jié),啟動(dòng)應(yīng)用程序Activity已經(jīng)走到ActivityTaskManagerService中,如果你熟悉前以往版本的Android源碼,你肯定會(huì)知道ActivityManagerService,而在Android 10 中則將AMS用于管理Activity及其容器(任務(wù),堆棧,顯示等)的系統(tǒng)服務(wù)分離出來(lái)放到ATMS中,也許是谷歌不想讓AMS的代碼越來(lái)越膨脹吧(Android 10中AMS代碼有一萬(wàn)九千行)。好了,接著看到ATMS的startActivity方法
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());//1
}
- 由以上代碼,繼續(xù)調(diào)用了startActivityAsUser方法,該方法多傳入了用戶的ID,接著會(huì)判斷是否有權(quán)限調(diào)用,沒(méi)有權(quán)限調(diào)用則拋出異常,否則獲取用戶id用于后續(xù)進(jìn)程間Binder通信。接著繼續(xù)看startActivityAsUser方法
frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
true /*validateIncomingUser*/);//1
}
int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// TODO: Switch to user app stacks here.
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(bOptions)
.setMayWait(userId)
.execute();//2
}
- 由以上代碼,注釋1調(diào)用了ATMS自己實(shí)現(xiàn)的startActivityAsUser方法,在注釋而2處構(gòu)造了ActivityStarter,此類收集了用于確定將意圖和標(biāo)志如何轉(zhuǎn)換為活動(dòng)以及關(guān)聯(lián)的任務(wù)和堆棧的所有邏輯,obtainStarter方法第二個(gè)參數(shù)代表啟動(dòng)Activity的意圖,接著調(diào)用了execute方法,
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) { //1
return startActivityMayWait(mRequest.caller, mRequest.callingUid,
mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid,
mRequest.intent, mRequest.resolvedType,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);//2
}
......
}
.......
}
- 由以上代碼看到注釋1,前面構(gòu)造ActivityStarter已經(jīng)傳入了用戶id,所以這里判斷條件成立,則繼續(xù)調(diào)用startActivityMayWait方法
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, int requestRealCallingPid, int requestRealCallingUid,
Intent intent, String resolvedType, IVoiceInteractionSession voiceSession,
IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
int userId, TaskRecord inTask, String reason,
boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
......
final ActivityRecord[] outRecord = new ActivityRecord[1];//1
int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent,
allowBackgroundActivityStart);//2
......
return res;
}
}
- 由以上代碼,可以看到注釋1處創(chuàng)建了一個(gè)ActivityRecord數(shù)組,ActivityRecord代表一個(gè)Activity,接著調(diào)用了startActivity方法,
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
SafeActivityOptions options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup,
PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) {
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
int err = ActivityManager.START_SUCCESS;
// Pull the optional Ephemeral Installer-only bundle out of the options early.
final Bundle verificationBundle
= options != null ? options.popAppVerificationBundle() : null;
WindowProcessController callerApp = null;
if (caller != null) {//1
callerApp = mService.getProcessController(caller);//2
if (callerApp != null) {
callingPid = callerApp.getPid();
callingUid = callerApp.mInfo.uid;
} else {
Slog.w(TAG, "Unable to find app for caller " + caller
+ " (pid=" + callingPid + ") when starting: "
+ intent.toString());
err = ActivityManager.START_PERMISSION_DENIED;
}
}
.......
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;//3
}
......
final int res = startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
true /* doResume */, checkedOptions, inTask, outActivity, restrictedBgActivity);//4
.....
return res;
}
- 由以上代碼,startActivity里面有很多的邏輯代碼,這里只看一些重點(diǎn)的邏輯代碼,主要做了兩個(gè)事情:
(1)注釋1處判斷IApplicationThread是否為空,前面第一小節(jié)我們就已經(jīng)提到過(guò),它代表的就是Launcher進(jìn)程的ApplicationThread,注釋2通過(guò)與即將要啟動(dòng)的應(yīng)用程序進(jìn)程建立聯(lián)系,應(yīng)用程序進(jìn)程的是fork到Zyote進(jìn)程,這里先不進(jìn)行展開(kāi)了,先專注Activity啟動(dòng)流程。接著注釋3創(chuàng)建ActivityRecord代表即將要啟動(dòng)的Activity,包含了Activity的所有信息,并賦值給上一步驟中創(chuàng)建的ActivityRecord類型的outActivity,注釋4則繼續(xù)調(diào)用startActivity方法
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
int result = START_CANCELED;
final ActivityStack startedActivityStack;
try {
mService.mWindowManager.deferSurfaceLayout();
result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, outActivity, restrictedBgActivity);//1
}
........
return result;
}
- 由以上代碼,注釋1處startActivity又調(diào)用了startActivityUnchecked方法
frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
// Note: This method should only be called from {@link startActivity}.
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
ActivityRecord[] outActivity, boolean restrictedBgActivity) {
......
final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTaskRecord() : null;
// Should this be considered a new task?
int result = START_SUCCESS;
if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
&& (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { //1
newTask = true;
result = setTaskFromReuseOrCreateNewTask(taskToAffiliate); //2
}
........
if (mDoResume) {
final ActivityRecord topTaskActivity =
mStartActivity.getTaskRecord().topRunningActivityLocked();
if (!mTargetStack.isFocusable()
|| (topTaskActivity != null && topTaskActivity.mTaskOverlay
&& mStartActivity != topTaskActivity)) {
mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS);
mTargetStack.getDisplay().mDisplayContent.executeAppTransition();
} else {
// If the target stack was not previously focusable (previous top running activity
// on that stack was not visible) then any prior calls to move the stack to the
// will not update the focused stack. If starting the new activity now allows the
// task stack to be focusable, then ensure that we now update the focused stack
// accordingly.
if (mTargetStack.isFocusable()
&& !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
mRootActivityContainer.resumeFocusedStacksTopActivities(
mTargetStack, mStartActivity, mOptions);//3
}
}
- 由上代碼注釋1,在前面第一節(jié)Launcher部分中有提到過(guò)設(shè)置了Flag為FLAG_ACTIVITY_NEW_TASK,所以注意判斷條件成立,則調(diào)用setTaskFromReuseOrCreateNewTask,它內(nèi)部會(huì)創(chuàng)建的TaskRecord(代表Activity的任務(wù)棧),并將傳入的TaskRecord對(duì)象設(shè)置給代表啟動(dòng)的Activity的ActivityRecord,接著在注釋3調(diào)用了RootActivityContainer的resumeFocusedStacksTopActivities方法,RootActivityContainer 將一些東西從ActivityStackSupervisor中分離出來(lái)。目的是將其與RootWindowContainer合并,作為統(tǒng)一層次結(jié)構(gòu)的一部分,接著看它的resumeFocusedStacksTopActivities方法
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
boolean resumeFocusedStacksTopActivities(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
......
boolean result = false;
if (targetStack != null && (targetStack.isTopStackOnDisplay()
|| getTopDisplayFocusedStack() == targetStack)) {
result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);//1
}
.......
return result;
}
- 由以上代碼注釋1處,又調(diào)用了ActivityStack的resumeTopActivityUncheckedLocked方法,ActivityStack應(yīng)該算是任務(wù)棧的描述,它管理者一個(gè)應(yīng)用的所有TaskRecord和他們的狀態(tài),接著看到它的resumeTopActivityUncheckedLocked方法
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
//確保棧頂 activity 為Resume
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
if (mInResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// 防止遞歸
mInResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options); //1
........
} finally {
mInResumeTopActivity = false;
}
return result;
}
- 由以上代碼,在注釋1處接著又調(diào)用ActivityStack的resumeTopActivityInnerLocked方法
frameworks/base/services/core/java/com/android/server/wm/ActivityStack.java
@GuardedBy("mService")
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
....
// Whoops, need to restart this activity!
........
mStackSupervisor.startSpecificActivityLocked(next, true, true);//1
........
}
- 由以上代碼看到注釋1,resumeTopActivityInnerLocked方法中邏輯非常多,這里直接精簡(jiǎn)到這一句關(guān)鍵代碼,調(diào)用了ActivityStackSupervisor的startSpecificActivityLocked方法
ActivityStackSupervisor 啟動(dòng)Activity
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Activity應(yīng)用程序進(jìn)程是否已經(jīng)準(zhǔn)備好
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) { //1
try {
realStartActivityLocked(r, wpc, andResume, checkConfig); //2
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
.......
}
.......
try {
.......
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());//3
mService.mH.sendMessage(msg);
}
........
}
- 如上代碼所示注釋1,判斷要啟動(dòng)的應(yīng)用程序進(jìn)程是否已經(jīng)準(zhǔn)備好,hasThread則是確定應(yīng)用程序進(jìn)程的IApplicationThread是否存在,如果存在則調(diào)用ActivityStackSupervisor的realStartActivityLocked方法啟動(dòng)Activity;如果是第一次啟動(dòng),則應(yīng)用程序進(jìn)程沒(méi)有準(zhǔn)備好,則會(huì)走到注釋3處啟動(dòng)應(yīng)用程序進(jìn)程,本文先跳過(guò),留到下篇文章在探究。接下來(lái)繼續(xù)看到realStartActivityLocked方法
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
.......
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);//1
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
// TODO: Have this take the merged configuration instead of separate global
// and override configs.
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));//2
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);//3
.......
return true;
}
- 由以上代碼注釋1處,創(chuàng)建了ClientTransaction對(duì)象,它是包含一系列消息的容器,可以將其發(fā)送到客戶端,這個(gè)客戶端就我們要啟動(dòng)的應(yīng)用程序Activity,注釋2處將前面一路傳遞進(jìn)來(lái)的啟動(dòng)Activity參數(shù)封裝成了LaunchActivityItem請(qǐng)求request對(duì)象,接著我們看到注釋3,這里調(diào)用了ClientLifecycleManager的scheduleTransaction方法,它的初始化在AMTS構(gòu)造方法中,并傳入了ClientTransaction參數(shù),接著看到ClientLifecycleManager的scheduleTransaction方法
ClientLifecycleManager(ActivityThread)處理ClientTransaction
frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();//1
transaction.schedule();//2
if (!(client instanceof Binder)) {
// If client is not an instance of Binder - it's a remote call and at this point it is
// safe to recycle the object. All objects used for local calls will be recycled after
// the transaction is executed on client in ActivityThread.
transaction.recycle();
}
}
- 到此,基本上已經(jīng)比較清晰了,注釋1處獲取了要啟動(dòng)的應(yīng)用程序進(jìn)程的IApplicationThread,上一步中創(chuàng)建ClientTransaction對(duì)象時(shí)已經(jīng)將其賦值給ClientTransaction的變量mClient,隨后scheduleTransaction判斷是否支持進(jìn)程間通信;注釋二處則調(diào)用了ClientTransaction的schedule方法,
frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java
/** Target client. */
private IApplicationThread mClient;
/** Schedule the transaction after it was initialized. It will be send to client and all its
* individual parts will be applied in the following sequence:
* 1. The client calls {@link #preExecute(ClientTransactionHandler)}, which triggers all work
* that needs to be done before actually scheduling the transaction for callbacks and
* lifecycle state request.
* 2. The transaction message is scheduled.
* 3. The client calls {@link TransactionExecutor#execute(ClientTransaction)}, which executes
* all callbacks and necessary lifecycle transitions.
*/
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this); //1
}
通過(guò)以上代碼,注釋1處mClient則代表要啟動(dòng)的應(yīng)用程序進(jìn)程的IApplicationThread,而當(dāng)前還處于ATMS服務(wù)的進(jìn)程,也就是SystemServer進(jìn)程,這時(shí)ATMS要與即將啟動(dòng)的應(yīng)用程序進(jìn)程通信則通過(guò)IApplicationThread來(lái)執(zhí)行AIDL,IApplicationThread實(shí)現(xiàn)為ApplicationThread,它是ActivityThread的內(nèi)部類,所以前面也說(shuō)過(guò)ApplicationThread為進(jìn)程間通信的橋梁,注釋1處則相當(dāng)于是IApplicationThread.scheduleTransaction,并將包含要啟動(dòng)Activity信息的ClientTransaction傳遞到了應(yīng)用程序進(jìn)程,下一節(jié)就從IApplicationThread講起。
為了更好理解,看看AMTS調(diào)用到ApplicationThread時(shí)序圖來(lái)對(duì)上面的步驟進(jìn)行回顧
ActivityThread啟動(dòng)Activity
ApplicationThread 處理進(jìn)程間數(shù)據(jù)通信
- 接著上一節(jié)的內(nèi)容,我們從ApplicationThread的scheduleTransaction方法開(kāi)始
frameworks/base/core/java/android/app/ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);//1
}
}
- 由以上代碼,注釋1處調(diào)用了ActivityThread的scheduleTransaction方法,ActivityThread繼承了ClientTransactionHandler,scheduleTransaction在里面實(shí)現(xiàn)
frameworks/base/core/java/android/app/ClientTransactionHandler.java
/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
ActivityThread.H 線程間消息處理
- 可以看到這里發(fā)送了一個(gè)Handler消息,而ActivityThread.H則是ActivityThread的內(nèi)部Handler,它是整個(gè)應(yīng)用程序的主線程Handler,這里為什么需要切換線程呢?其原因?yàn)榍懊鍭TMS進(jìn)程間通信則是運(yùn)行在Binder線程,而Android更新UI則需要在主線程,接著看到ActivityThread.H的消息處理
class H extends Handler {
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;//1
mTransactionExecutor.execute(transaction);//2
......
break;
}
}
TransactionExecutor
- 由以上代碼,看到注釋1處,獲取了由ATMS傳遞過(guò)來(lái)的啟動(dòng)Activity進(jìn)程的數(shù)據(jù),注釋2處調(diào)用了TransactionExecutor的來(lái)處理ClientTransaction的數(shù)據(jù),接著看到它的execute方法
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
.......
executeCallbacks(transaction); //
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
- 由以上代碼注釋1處接著調(diào)用了TransactionExecutor的executeCallbacks方法
frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
/** Cycle through all states requested by callbacks and execute them at proper times. */
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
if (callbacks == null || callbacks.isEmpty()) {
// No callbacks to execute, return early.
return;
}
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");
final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
// In case when post-execution state of the last callback matches the final state requested
// for the activity in this transaction, we won't do the last transition here and do it when
// moving to final state instead (because it may contain additional parameters from server).
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
: UNDEFINED;
// Index of the last callback that requests some post-execution state.
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);
final int size = callbacks.size();
for (int i = 0; i < size; ++i) {
final ClientTransactionItem item = callbacks.get(i);//1
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
final int postExecutionState = item.getPostExecutionState();
final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
item.getPostExecutionState());
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
item.execute(mTransactionHandler, token, mPendingActions);//2
........
}
}
LaunchActivityItem
- 由以上代碼注釋1處,獲取的ClientTransactionItem則為第二小節(jié)中提到過(guò)的LaunchActivityItem對(duì)象,它繼承了ClientTransactionItem,并保存這需要啟動(dòng)的Activity數(shù)據(jù),接著看到注釋2 LaunchActivityItem的execute方法。
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
mPendingResults, mPendingNewIntents, mIsForward,
mProfilerInfo, client, mAssistToken);//1
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);//2
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
- 由以上代碼,注釋1處恢復(fù)了要啟動(dòng)的Activity的數(shù)據(jù),ActivityClientRecord是ActivityThread的內(nèi)部類,這里的client為ClientTransactionHandler,而前面已經(jīng)說(shuō)過(guò)ActivityThread繼承ClientTransactionHandler,所以這里的注釋2處調(diào)用的就是ActivityThread的handleLaunchActivity方法
frameworks/base/core/java/android/app/ActivityThread.java
/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
.......
final Activity a = performLaunchActivity(r, customIntent);//1
.......
return a;
}
- 由以上代碼注釋1處,繼續(xù)調(diào)用了ActivityThread的performLaunchActivity方法來(lái)啟動(dòng)Activity,返回的也是Activity實(shí)例。所以performLaunchActivity方法才是啟動(dòng)Activity實(shí)例的核心代碼。
Core Activity Launch
frameworks/base/core/java/android/app/ActivityThread.java
/** Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;//1
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);//2
}
ComponentName component = r.intent.getComponent();//3
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//應(yīng)用程序Context的創(chuàng)建
ContextImpl appContext = createBaseContextForActivity(r);//4
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//創(chuàng)建Activity的實(shí)例
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);//5
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
try {
//應(yīng)用程序Application的創(chuàng)建
Application app = r.packageInfo.makeApplication(false, mInstrumentation);//6
......
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
// 通過(guò)Activity的 attach 方法將 context等各種數(shù)據(jù)與Activity綁定,初始化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, window, r.configCallback,
r.assistToken); //7
......
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
......
r.activity = activity;
}
r.setState(ON_CREATE);
.......
}
return activity;
}
- 由以上代碼,注釋1處獲取了前面保存啟動(dòng)應(yīng)用程序信息的ActivityClientRecord中的應(yīng)用程序信息,包括應(yīng)用程序在清單文件中注冊(cè)了哪些四大組件,啟動(dòng)的根Activity是什么,并在注釋2處通過(guò)getPackageInfo方法獲取LoadedApk描述對(duì)應(yīng)Apk文件資源,注釋3處的ComponentName類獲取則對(duì)應(yīng)啟動(dòng)Activity的包名和類名,注釋4處則生成了啟動(dòng)應(yīng)用程序的Base上下文環(huán)境Context,注釋5處通過(guò)注釋3獲取的類名,通過(guò)類加載器和Intent對(duì)象實(shí)例化了Activity對(duì)象,注釋6則根據(jù)注釋2處獲取Apk描述對(duì)象LoadedApk創(chuàng)建了應(yīng)用程序的Application對(duì)象,并在makeApplication方法中調(diào)用了它的OnCreate方法,所以應(yīng)用程序最新啟動(dòng)的是Application才到根Activity,注釋7處則前面創(chuàng)建的Context、Application、Window對(duì)象與Activity關(guān)聯(lián)來(lái)初始化Activity,最后注釋8處還繼續(xù)調(diào)用了Instrumentation對(duì)象的callActivityOnCreate方法。接著往下看
Activity的 OnCreate方法調(diào)用
frameworks/base/core/java/android/app/Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle, persistentState);//1
postPerformCreate(activity);
}
- 由以上代碼,注釋1處又調(diào)用了Activity的performCreate方法,繼續(xù)往下看
frameworks/base/core/java/android/app/Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
dispatchActivityPreCreated(icicle);
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
if (persistentState != null) {
onCreate(icicle, persistentState);//1
} else {
onCreate(icicle);
}
.......
}
- 最終,在已經(jīng)實(shí)例初始化好的Activity調(diào)用它的performCreate方法中又掉用了onCreate方法(注釋1)。至此,也就是整個(gè)應(yīng)用程序的Activity啟動(dòng)過(guò)程我們已經(jīng)走完了。
-
為了更好理解,看看ActivityThread啟動(dòng)Activity的時(shí)序圖來(lái)對(duì)上面的步驟進(jìn)行回顧
ActivityThread啟動(dòng)Activity時(shí)序圖.jpg
最后
- 通過(guò)本文,基本上將引用程序啟動(dòng)根的Activity啟動(dòng)流程走了一遍,但是其中還有一點(diǎn)沒(méi)說(shuō)展開(kāi)的就是應(yīng)用程序進(jìn)程的啟動(dòng)過(guò)程,這一部分內(nèi)容將通過(guò)后續(xù)文章繼續(xù)探究。。如果文章中有寫(xiě)得不對(duì)的地方,歡迎在留言區(qū)留言大家一起討論,共同學(xué)習(xí)進(jìn)步。如果覺(jué)得我的文章給予你幫助,也請(qǐng)給我一個(gè)喜歡和關(guān)注。
參考
- 書(shū)籍《Android 進(jìn)階解密》
- Android源碼地址