在進階Android的路上倔监,了解理解一個應用根Activity啟動流程可以作為一個切入點批旺,由此展開進階之路销睁。平時我們開發(fā)的應用都是展示在Android系統(tǒng)桌面上供璧,這個系統(tǒng)桌面其實也是一個Android應用,它叫Launcher冻记。所以本文通過源碼層面從Launcher調用ATMS睡毒,ATMS調用ApplicationThread,最后ActivityThread啟動Activity三個過程了解Activity啟動流程(文中源碼基于Android 10 )冗栗。
首先來個腦圖演顾,對于整體模塊在大腦中形成一個整體印象
Launcher到ActivityTaskManagerService
Launcher 調用 Activity
- 至于Launcher如何加載展示應用程序到界面這里先略過(與PMS相關),本文先關注Activity啟動過程隅居。當我們點擊系統(tǒng)桌面的應用圖標钠至,直接響應的則是Launcher這個應用程序,會調用它的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;
}
- 通過以上源碼胎源,在注釋1調用的是父類的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涕蚤,設置啟動Activity的Flag為FLAG_ACTIVITY_NEW_TASK宪卿,設置這個Flag則Activity的啟動就會在新的任務棧中啟動,后面還會遇到它赞季;接著看到注釋2愧捕,調用了startActivity的方法奢驯,顯然這就是調用了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方法調用的是startActivityForResult方法瘪阁,這個方法日常開發(fā)啟動Activity有參數(shù)回調也會使用撒遣,這里參數(shù)傳入-1邮偎,表明Launcher啟動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 {
......
}
}
- 通過以上源碼看到注釋1义黎,mParent的聲明類型為Activity禾进,當前還是正在起Activity,mParent == null成立廉涕,看到注釋2調用了Instrumentation類的execStartActivity方法泻云,Instrumentation允許您監(jiān)視系統(tǒng)與應用程序之間的所有交互(Instrumentation注釋:allowing you to monitor all of the interaction the system has with the application.),接著看到它的execStartActivity方法
Instrumentation 調用到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;
}
- 通過以上源碼看到注釋1狐蜕,這里獲取了IApplicationThread宠纯,如果你了解Binder,第一反應就應該很清晰层释,目前處于Launcher應用程序進程婆瓜,要啟動Activity則需要請求系統(tǒng)服務進程(SystemServer),而Android進程間通信則可以使用Binder,而這里實現(xiàn)方式為AIDL贡羔,它的實現(xiàn)類為ActivityThread的內部類ApplicationThread廉白,而ApplicationThread作用則為應用程序進程和系統(tǒng)服務進程通信的橋梁,后面還會繼續(xù)提到乖寒;接著看到注釋2猴蹂,這里調用ActivityTaskManager.getService則可以獲取ActivityTaskManagerService的代理對象,看看他的實現(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宵统,通過ServiceManager來獲取遠程服務ActivityTaskManagerService晕讲,ServiceManager底層最終調用的還是c++層的ServiceManager,它是Binder的守護服務马澈,通過它能夠獲取在Android系統(tǒng)啟動時注冊的系統(tǒng)服務瓢省,這其中就包含這里提到的ATMS;接著回到注釋2建立 Launcher與 ATMS的連接痊班,這樣回到execStartActivity方法贩汉,Launcher就通過調用ATMS的startActivity方法將啟動Activity的數(shù)據(jù)交給ATMS服務來處理了。
-
為了更好理解季春,看看Launcher調用到ActivityTaskManagerService時序圖來對上面的步驟進行回顧
ActivityTaskManagerService 調用ApplicationThread
ATMS處理啟動Activity請求
- 通過上一小節(jié)徙菠,啟動應用程序Activity已經(jīng)走到ActivityTaskManagerService中,如果你熟悉前以往版本的Android源碼凝果,你肯定會知道ActivityManagerService祝迂,而在Android 10 中則將AMS用于管理Activity及其容器(任務,堆棧器净,顯示等)的系統(tǒng)服務分離出來放到ATMS中型雳,也許是谷歌不想讓AMS的代碼越來越膨脹吧(Android 10中AMS代碼有一萬九千行)。好了,接著看到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ù)調用了startActivityAsUser方法沿量,該方法多傳入了用戶的ID,接著會判斷是否有權限調用冤荆,沒有權限調用則拋出異常朴则,否則獲取用戶id用于后續(xù)進程間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調用了ATMS自己實現(xiàn)的startActivityAsUser方法乌妒,在注釋而2處構造了ActivityStarter,此類收集了用于確定將意圖和標志如何轉換為活動以及關聯(lián)的任務和堆棧的所有邏輯外邓,obtainStarter方法第二個參數(shù)代表啟動Activity的意圖芥被,接著調用了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坐榆,前面構造ActivityStarter已經(jīng)傳入了用戶id拴魄,所以這里判斷條件成立,則繼續(xù)調用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)建了一個ActivityRecord數(shù)組匹中,ActivityRecord代表一個Activity,接著調用了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里面有很多的邏輯代碼顶捷,這里只看一些重點的邏輯代碼,主要做了兩個事情:
(1)注釋1處判斷IApplicationThread是否為空屎篱,前面第一小節(jié)我們就已經(jīng)提到過服赎,它代表的就是Launcher進程的ApplicationThread,注釋2通過與即將要啟動的應用程序進程建立聯(lián)系交播,應用程序進程的是fork到Zyote進程重虑,這里先不進行展開了,先專注Activity啟動流程。接著注釋3創(chuàng)建ActivityRecord代表即將要啟動的Activity秦士,包含了Activity的所有信息缺厉,并賦值給上一步驟中創(chuàng)建的ActivityRecord類型的outActivity,注釋4則繼續(xù)調用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又調用了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部分中有提到過設置了Flag為FLAG_ACTIVITY_NEW_TASK,所以注意判斷條件成立曹傀,則調用setTaskFromReuseOrCreateNewTask辐脖,它內部會創(chuàng)建的TaskRecord(代表Activity的任務棧),并將傳入的TaskRecord對象設置給代表啟動的Activity的ActivityRecord皆愉,接著在注釋3調用了RootActivityContainer的resumeFocusedStacksTopActivities方法嗜价,RootActivityContainer 將一些東西從ActivityStackSupervisor中分離出來落萎。目的是將其與RootWindowContainer合并,作為統(tǒng)一層次結構的一部分炭剪,接著看它的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處,又調用了ActivityStack的resumeTopActivityUncheckedLocked方法翔脱,ActivityStack應該算是任務棧的描述奴拦,它管理者一個應用的所有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處接著又調用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方法中邏輯非常多,這里直接精簡到這一句關鍵代碼疚沐,調用了ActivityStackSupervisor的startSpecificActivityLocked方法
ActivityStackSupervisor 啟動Activity
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Activity應用程序進程是否已經(jīng)準備好
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暂氯,判斷要啟動的應用程序進程是否已經(jīng)準備好,hasThread則是確定應用程序進程的IApplicationThread是否存在亮蛔,如果存在則調用ActivityStackSupervisor的realStartActivityLocked方法啟動Activity痴施;如果是第一次啟動,則應用程序進程沒有準備好究流,則會走到注釋3處啟動應用程序進程辣吃,本文先跳過,留到下篇文章在探究芬探。接下來繼續(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對象,它是包含一系列消息的容器偷仿,可以將其發(fā)送到客戶端哩簿,這個客戶端就我們要啟動的應用程序Activity,注釋2處將前面一路傳遞進來的啟動Activity參數(shù)封裝成了LaunchActivityItem請求request對象酝静,接著我們看到注釋3节榜,這里調用了ClientLifecycleManager的scheduleTransaction方法,它的初始化在AMTS構造方法中别智,并傳入了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處獲取了要啟動的應用程序進程的IApplicationThread浓若,上一步中創(chuàng)建ClientTransaction對象時已經(jīng)將其賦值給ClientTransaction的變量mClient,隨后scheduleTransaction判斷是否支持進程間通信蛇数;注釋二處則調用了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
}
通過以上代碼,注釋1處mClient則代表要啟動的應用程序進程的IApplicationThread耳舅,而當前還處于ATMS服務的進程碌上,也就是SystemServer進程倚评,這時ATMS要與即將啟動的應用程序進程通信則通過IApplicationThread來執(zhí)行AIDL,IApplicationThread實現(xiàn)為ApplicationThread馏予,它是ActivityThread的內部類天梧,所以前面也說過ApplicationThread為進程間通信的橋梁,注釋1處則相當于是IApplicationThread.scheduleTransaction霞丧,并將包含要啟動Activity信息的ClientTransaction傳遞到了應用程序進程呢岗,下一節(jié)就從IApplicationThread講起。
為了更好理解蛹尝,看看AMTS調用到ApplicationThread時序圖來對上面的步驟進行回顧
ActivityThread啟動Activity
ApplicationThread 處理進程間數(shù)據(jù)通信
- 接著上一節(jié)的內容后豫,我們從ApplicationThread的scheduleTransaction方法開始
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處調用了ActivityThread的scheduleTransaction方法突那,ActivityThread繼承了ClientTransactionHandler挫酿,scheduleTransaction在里面實現(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ā)送了一個Handler消息,而ActivityThread.H則是ActivityThread的內部Handler愕难,它是整個應用程序的主線程Handler早龟,這里為什么需要切換線程呢?其原因為前面ATMS進程間通信則是運行在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傳遞過來的啟動Activity進程的數(shù)據(jù)翘悉,注釋2處調用了TransactionExecutor的來處理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處接著調用了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é)中提到過的LaunchActivityItem對象妖混,它繼承了ClientTransactionItem,并保存這需要啟動的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處恢復了要啟動的Activity的數(shù)據(jù)弊予,ActivityClientRecord是ActivityThread的內部類祥楣,這里的client為ClientTransactionHandler,而前面已經(jīng)說過ActivityThread繼承ClientTransactionHandler汉柒,所以這里的注釋2處調用的就是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ù)調用了ActivityThread的performLaunchActivity方法來啟動Activity,返回的也是Activity實例碾褂。所以performLaunchActivity方法才是啟動Activity實例的核心代碼兽间。
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);
}
//應用程序Context的創(chuàng)建
ContextImpl appContext = createBaseContextForActivity(r);//4
Activity activity = null;
try {
java.lang.ClassLoader cl = appContext.getClassLoader();
//創(chuàng)建Activity的實例
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 {
//應用程序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);
// 通過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處獲取了前面保存啟動應用程序信息的ActivityClientRecord中的應用程序信息嘀略,包括應用程序在清單文件中注冊了哪些四大組件恤溶,啟動的根Activity是什么,并在注釋2處通過getPackageInfo方法獲取LoadedApk描述對應Apk文件資源帜羊,注釋3處的ComponentName類獲取則對應啟動Activity的包名和類名咒程,注釋4處則生成了啟動應用程序的Base上下文環(huán)境Context,注釋5處通過注釋3獲取的類名讼育,通過類加載器和Intent對象實例化了Activity對象帐姻,注釋6則根據(jù)注釋2處獲取Apk描述對象LoadedApk創(chuàng)建了應用程序的Application對象,并在makeApplication方法中調用了它的OnCreate方法窥淆,所以應用程序最新啟動的是Application才到根Activity,注釋7處則前面創(chuàng)建的Context巍杈、Application忧饭、Window對象與Activity關聯(lián)來初始化Activity,最后注釋8處還繼續(xù)調用了Instrumentation對象的callActivityOnCreate方法筷畦。接著往下看
Activity的 OnCreate方法調用
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處又調用了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)實例初始化好的Activity調用它的performCreate方法中又掉用了onCreate方法(注釋1)吼砂。至此,也就是整個應用程序的Activity啟動過程我們已經(jīng)走完了鼎文。
-
為了更好理解渔肩,看看ActivityThread啟動Activity的時序圖來對上面的步驟進行回顧
最后
- 通過本文,基本上將引用程序啟動根的Activity啟動流程走了一遍拇惋,但是其中還有一點沒說展開的就是應用程序進程的啟動過程周偎,這一部分內容將通過后續(xù)文章繼續(xù)探究。撑帖。如果文章中有寫得不對的地方蓉坎,歡迎在留言區(qū)留言大家一起討論,共同學習進步胡嘿。如果覺得我的文章給予你幫助蛉艾,也請給我一個喜歡和關注。
參考
- 書籍《Android 進階解密》
- Android源碼地址