、Service、BroadcastReceiver、ContentProvider。我們最常接觸也是用戶直接感受到的就是Activity了,今天來就說說Android啓動的執行過程和工作原理。
Activity是一種 展示型組件,用於展示給用戶一個可以交互的頁面。Activity是Android中最重要的組件,對用戶來說,所有的Activity就是一個App的全部,而其他組件用戶是不能直接感知的。在開發層面,要啓動一個Activity可以使用Intent,分顯式和隱式,並且還可以設置Activity的啓動模式。
Android系統對四大組件都做了很大程度的封裝,這樣我們可以快速使用組件。Activity的啓動在系統封裝後,變的極爲簡單,顯示啓動activity代碼如下:
Intent intent = new Intent(this, TestActivity.class);
this.startActivity(intent);
這樣就可以啓動TestActivity了,那麼問題來了,
- 這個代碼是如何啓動一個Activity的?
- 裏面做了哪些事情?
- onCreate這些生命週期是何時執行的?
- Activity對象何時創建的?
- 視圖是怎麼處理以及何時可見的?
那麼爲啥需要了解這些問題呢?不瞭解 ,平時開發好像也沒啥問題啊。其實不然,解決這些問題後,你會對Android系統有更深層次的理解,也會學習到系統源碼優秀的設計。並且對解決一些高級問題和深入的性能優化問題有很大幫助,是技術進階的必要階段。這就需要我們通過閱讀源碼來梳理這些問題,但另一方面,系統源碼是很龐大繁雜的,我們需要帶着問題抓住主流程,不能陷入代碼細節——這是閱讀系統源碼以及其他第三方庫源碼的正確姿勢。
二、流程分析
2.1 Activity啓動的發起
下面我們就來對Activity的工作流程進行梳理,達到對Activity整體流程的掌握。從startActivity方法開始,會走到startActivityForResult方法:
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
...
}
}
看到裏面調用了mInstrumentation.execStartActivity方法,其中一個參數mMainThread.getApplicationThread(),它的類型是ApplicationThread,ApplicationThread是ActivityThread的內部類,繼承IApplicationThread.Stub,也是個Binder對象,在Activity工作流程中有重要作用。而Instrumentation具有跟蹤application及activity生命週期的功能,用於android 應用測試框架中代碼檢測。接着看下mInstrumentation.execStartActivity方法:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
...
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);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
這裏看到Activity的啓動又交給了ActivityTaskManager.getService(),這是啥?跟進去看看:
//ActivityTaskManager
public static IActivityTaskManager getService() {
return IActivityTaskManagerSingleton.get();
}
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
new Singleton<IActivityTaskManager>() {
@Override
protected IActivityTaskManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
return IActivityTaskManager.Stub.asInterface(b);
}
};
看到IBinder這個標誌,這裏你應該明白了:這裏是獲取一個跨進程的服務。獲取的什麼服務呢?是ActivityTaskManagerService(ATMS),它繼承於IActivityTaskManager.Stub,是個Binder對象,並且是通過單例提供服務的。 ATMS是用於管理Activity及其容器(任務、堆棧、顯示等)的系統服務,運行在系統服務進程(system_server)之中。
值得說明的是,ATMS是在Android10中新增的,分擔了之前ActivityManagerService(AMS)的一部分功能(activity task相關)。
在Android10 之前 ,這個地方獲取的是服務是AMS。查看Android10的AMS,你會發現startActivity方法內也是調用了ATMS的startActivity方法。所以在理解上,ATMS就隸屬於AMS。
接着看,ActivityTaskManager.getService().startActivity有個返回值result,且調用了checkStartActivityResult(result, intent):
public static void checkStartActivityResult(int res, Object intent) {
if (!ActivityManager.isStartResultFatalError(res)) {
return;
}
switch (res) {
case ActivityManager.START_INTENT_NOT_RESOLVED:
case ActivityManager.START_CLASS_NOT_FOUND:
if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
throw new ActivityNotFoundException(
"Unable to find explicit activity class "
+ ((Intent)intent).getComponent().toShortString()
+ "; have you declared this activity in your AndroidManifest.xml?");
throw new ActivityNotFoundException(
"No Activity found to handle " + intent);
case ActivityManager.START_PERMISSION_DENIED:
throw new SecurityException("Not allowed to start activity "
+ intent);
...
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);
default:
throw new AndroidRuntimeException("Unknown error code "
+ res + " when starting " + intent);
}
}
這是用來檢查Activity啓動的結果,如果發生致命錯誤,就會拋出對應的異常。看到第一個case中就拋出了 have you declared this activity in your AndroidManifest.xml?——如果Activity沒在Manifest中註冊就會有這個錯誤。
2.2 Activity的管理——ATMS
好了,到這裏,Activity的啓動就跨進程(IPC)的轉移到系統進程提供的服務ATMS中了,接着看ATMS的startActivity:
//ActivityTaskManagerService
@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());
}
@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*/);
}
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();
}
跟到startActivityAsUser中,通過getActivityStartController().obtainStarter方法獲取ActivityStarter實例 然後調用一系列方法,最後的execute()方法是開始啓動activity:
int execute() {
try {
// TODO(b/64750076): Look into passing request directly to these methods to allow
// for transactional diffs and preprocessing.
if (mRequest.mayWait) {
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);
} else {
return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent,
mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo,
mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
mRequest.resultWho, mRequest.requestCode, mRequest.callingPid,
mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid,
mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions,
mRequest.ignoreTargetSecurity, mRequest.componentSpecified,
mRequest.outActivity, mRequest.inTask, mRequest.reason,
mRequest.allowPendingRemoteAnimationRegistryLookup,
mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart);
}
} finally {
onExecutionComplete();
}
}
分了兩種情況,不過 不論startActivityMayWait還是startActivity最終都是走到下面這個startActivity方法:
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);
} finally {
final ActivityStack currentStack = r.getActivityStack();
startedActivityStack = currentStack != null ? currentStack : mTargetStack;
...
}
postStartActivityProcessing(r, result, startedActivityStack);
return result;
}
裏面有調用了startActivityUnchecked方法,之後調用RootActivityContainer的resumeFocusedStacksTopActivities方法。RootActivityContainer是Android10新增的類,分擔了之前ActivityStackSupervisor的部分功能。接着跳轉到ActivityStack的resumeTopActivityUncheckedLocked方法:
//ActivityStack
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);
final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
} finally {
mInResumeTopActivity = false;
}
return result;
}
跟進resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
// 暫停上一個Activity
pausing |= startPausingLocked(userLeaving, false, next, false);
}
...
//這裏next.attachedToProcess(),只有啓動了的Activity纔會返回true
if (next.attachedToProcess()) {
...
try {
final ClientTransaction transaction =
ClientTransaction.obtain(next.app.getThread(), next.appToken);
...
//啓動了的Activity就發送ResumeActivityItem事務給客戶端了,後面會講到
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
getDisplay().mDisplayContent.isNextTransitionForward()));
mService.getLifecycleManager().scheduleTransaction(transaction);
....
} catch (Exception e) {
....
mStackSupervisor.startSpecificActivityLocked(next, true, false);
return true;
}
....
} else {
....
// 繼續當前Activity,普通activity的正常啓動 關注這裏即可
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
先對上一個Activity執行pause操作,再執行當前創建操作,代碼最終進入到了ActivityStackSupervisor.startSpecificActivityLocked方法中:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
knownToBeDead = true;
}
...
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+ r.processName);
}
// 上面的wpc != null && wpc.hasThread()不滿足的話,說明沒有進程,就會取創建進程
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
有個判斷條件if (wpc != null && wpc.hasThread()),意思是是否啓動了應用進程,內部是通過IApplicationThread是否爲空來判斷。這裏我們只看已啓動應用進程的情況,及調用了realStartActivityLocked方法,,:
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);
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));
// 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);
...
return true;
}
中間有段代碼如上,通過 ClientTransaction.obtain( proc.getThread(), r.appToken)獲取了clientTransaction,其中參數proc.getThread()是IApplicationThread,就是前面提到的ApplicationThread在系統進程的代理。
ClientTransaction是包含一系列的待客戶端處理的事務的容器,客戶端接收後取出事務並執行。
接着看,使用clientTransaction.addCallback添加了LaunchActivityItem實例:
//都是用來發送到客戶端的
private List<ClientTransactionItem> mActivityCallbacks;
public void addCallback(ClientTransactionItem activityCallback) {
if (mActivityCallbacks == null) {
mActivityCallbacks = new ArrayList<>();
}
mActivityCallbacks.add(activityCallback);
}
看下LaunchActivityItem實例的獲取:
/** Obtain an instance initialized with provided params. */
public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info,
Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo,
String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state,
PersistableBundle persistentState, List<ResultInfo> pendingResults,
List<ReferrerIntent> pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo,
IBinder assistToken) {
LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class);
if (instance == null) {
instance = new LaunchActivityItem();
}
setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer,
voiceInteractor, procState, state, persistentState, pendingResults,
pendingNewIntents, isForward, profilerInfo, assistToken);
return instance;
}
new了一個LaunchActivityItem然後設置各種值。我們從名字就能看出,它就是用來啓動activity的。它是怎麼發揮作用的呢?接着看:
回到realStartActivityLocked方法,接着調用了mService.getLifecycleManager().scheduleTransaction(clientTransaction),mService是ActivityTaskManagerService,getLifecycleManager()方法獲取的是ClientLifecycleManager實例,它的scheduleTransaction方法如下:
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
transaction.schedule();
if (!(client instanceof Binder)) {
transaction.recycle();
}
}
就是調用ClientTransaction的schedule方法,那就看看:
public void schedule() throws RemoteException {
mClient.scheduleTransaction(this);
}
很簡單,就是調用IApplicationThread的scheduleTransaction方法。由於IApplicationThread是ApplicationThread在系統進程的代理,所以真正執行的地方就是 客戶端的ApplicationThread中了。也就是說,Activity啓動的操作又跨進程的還給了客戶端。
好了,到這裏我們稍稍梳理下:啓動Activity的操作從客戶端 跨進程 轉移到 ATMS,ATMS通過ActivityStarter、ActivityStack、ActivityStackSupervisor 對 Activity任務、activity棧、Activity記錄 管理後,又用過跨進程把正在啓動過程又轉移到了客戶端。
2.3 線程切換及消息處理——mH
接着上面的分析,我們找到ApplicationThread的scheduleTransaction方法:
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
ActivityThread.this.scheduleTransaction(transaction);
}
那就再看ActivityThread的scheduleTransaction方法,實際在其父類ClientTransactionHandler中:
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
使用sendMessage發送消息,參數是ActivityThread.H.EXECUTE_TRANSACTION和transaction,接着看:
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
if (DEBUG_MESSAGES) {
Slog.v(TAG,
"SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
}
Message msg = Message.obtain();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.arg2 = arg2;
if (async) {
msg.setAsynchronous(true);
}
mH.sendMessage(msg);
}
最後調用了mH.sendMessage(msg),mH是個啥?我們看看:
//ActivityThread
final H mH = new H();
class H extends Handler {
public static final int BIND_APPLICATION = 110;
@UnsupportedAppUsage
public static final int EXIT_APPLICATION = 111;
@UnsupportedAppUsage
public static final int RECEIVER = 113;
@UnsupportedAppUsage
public static final int CREATE_SERVICE = 114;
@UnsupportedAppUsage
public static final int SERVICE_ARGS = 115;
...
public static final int EXECUTE_TRANSACTION = 159;
public static final int RELAUNCH_ACTIVITY = 160;
...
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case EXIT_APPLICATION:
if (mInitialApplication != null) {
mInitialApplication.onTerminate();
}
Looper.myLooper().quit();
break;
case RECEIVER:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
handleReceiver((ReceiverData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CREATE_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: " + String.valueOf(msg.obj)));
handleCreateService((CreateServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case BIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
handleBindService((BindServiceData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
break;
case RELAUNCH_ACTIVITY:
handleRelaunchActivityLocally((IBinder) msg.obj);
break;
...
}
Object obj = msg.obj;
if (obj instanceof SomeArgs) {
((SomeArgs) obj).recycle();
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
}
mH是在創建ActivityThread實例時賦值的,是自定義Handler子類H的實例,也就是在ActivityThread的main方法中,並且初始化是已經主線程已經有了mainLooper,所以,使用這個mH來sendMessage就把消息發送到了主線程。
那麼是從哪個線程發送的呢?那就要看看ApplicationThread的scheduleTransaction方法是執行在哪個線程了。根據IPC知識,我們知道,服務器的Binder方法運行在Binder的線程池中,也就是說系統進行跨進程調用ApplicationThread的scheduleTransaction就是執行在Binder的線程池中的了。
到這裏,消息就在主線程處理了,那麼是怎麼處理Activity的啓動的呢?接着看。我們找到ActivityThread.H.EXECUTE_TRANSACTION這個消息的處理,就在handleMessage方法的倒數第三個case(就在上面代碼):取出ClientTransaction實例,調用TransactionExecutor的execute方法,那就看看:
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction.getActivityToken();
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
...
}
繼續跟進executeCallbacks方法:
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);
...
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
...
}
}
遍歷callbacks,調用ClientTransactionItem的execute方法,而我們這裏要關注的是ClientTransactionItem的子類LaunchActivityItem,看下它的execute方法:
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);
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
裏面調用了client.handleLaunchActivity方法,client是ClientTransactionHandler的實例,是在TransactionExecutor構造方法傳入的,TransactionExecutor創建是在ActivityThread中:
//ActivityThread
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
所以,client.handleLaunchActivity方法就是ActivityThread的handleLaunchActivity方法。
好了,到這裏 ApplicationThread把啓動Activity的操作,通過mH切到了主線程,走到了ActivityThread的handleLaunchActivity方法。
2.4 Activity啓動核心實現——初始化及生命週期
那就接着看:
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
...
final Activity a = performLaunchActivity(r, customIntent);
...
return a;
}
繼續跟performLaunchActivity方法,這裏就是activity 啓動的核心實現了:
/** activity 啓動的核心實現. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//1、從ActivityClientRecord獲取待啓動的Activity的組件信息
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//創建ContextImpl對象
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
//2、創建activity實例
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
..
}
try {
//3、創建Application對象(如果沒有的話)
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
...
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
//4、attach方法爲activity關聯上下文環境
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
//5、調用生命週期onCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
}
r.setState(ON_CREATE);
synchronized (mResourcesManager) {
mActivities.put(r.token, r);
}
}
...
return activity;
}
performLaunchActivity主要完成以下事情:
- 從ActivityClientRecord獲取待啓動的Activity的組件信息
- 通過mInstrumentation.newActivity方法使用類加載器創建activity實例
- 通過LoadedApk的makeApplication方法創建Application對象,內部也是通過mInstrumentation使用類加載器,創建後就調用了instrumentation.callApplicationOnCreate方法,也就是Application的onCreate方法。
- 創建ContextImpl對象並通過activity.attach方法對重要數據初始化,關聯了Context的具體實現ContextImpl,attach方法內部還完成了window創建,這樣Window接收到外部事件後就能傳遞給Activity了。
- 調用Activity的onCreate方法,是通過 mInstrumentation.callActivityOnCreate方法完成。
到這裏Activity的onCreate方法執行完,那麼onStart、onResume呢?
上面看到LaunchActivityItem,是用來啓動Activity的,也就是走到Activity的onCreate,那麼是不是有 "XXXActivityItem"呢? 有的:
- LaunchActivityItem 遠程App端的onCreate生命週期事務
- ResumeActivityItem 遠程App端的onResume生命週期事務
- PauseActivityItem 遠程App端的onPause生命週期事務
- StopActivityItem 遠程App端的onStop生命週期事務
- DestroyActivityItem 遠程App端onDestroy生命週期事務
另外梳理過程中涉及的幾個類:
- ClientTransaction 客戶端事務控制者
- ClientLifecycleManager 客戶端的生命週期事務控制者
- TransactionExecutor 遠程通信事務執行者
那麼我們再來看看ResumeActivityItem吧。
我們再來重新看看在ActivityStackSupervisor的realStartActivityLocked方法:
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);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
System.identityHashCode(r), r.info,
mergedConfiguration.getGlobalConfiguration(),
mergedConfiguration.getOverrideConfiguration(), r.compat,
r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
r.icicle, r.persistentState, results, newIntents,
dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
r.assistToken));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
//這裏ResumeActivityItem
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
...
return true;
}
前面只說了通過clientTransaction.addCallback添加LaunchActivityItem實例,在注意下面接着調用了clientTransaction.setLifecycleStateRequest(lifecycleItem)方法,lifecycleItem是ResumeActivityItem或PauseActivityItem實例,這裏我們關注ResumeActivityItem,先看下setLifecycleStateRequest方法:
/**
* Final lifecycle state in which the client activity should be after the transaction is
* executed.
*/
private ActivityLifecycleItem mLifecycleStateRequest;
public void setLifecycleStateRequest(ActivityLifecycleItem stateRequest) {
mLifecycleStateRequest = stateRequest;
}
mLifecycleStateRequest表示執行transaction後的最終的生命週期狀態。
繼續看處理ActivityThread.H.EXECUTE_TRANSACTION這個消息的處理,即TransactionExecutor的execute方法:
public void execute(ClientTransaction transaction) {
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");
final IBinder token = transaction.getActivityToken();
...
executeCallbacks(transaction);
executeLifecycleState(transaction);
...
}
前面我們關注的是executeCallbacks方法,現在看看executeLifecycleState方法:
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
if (lifecycleItem == null) {
// No lifecycle request, return early.
return;
}
final IBinder token = transaction.getActivityToken();
final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
...
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
這裏取出了ActivityLifecycleItem並且調用了它的execute方法,實際就是ResumeActivityItem的方法:
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
經過上面分析實際是走到ActivityThread的handleResumeActivity方法:
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
...
// performResumeActivity內部會走onStart、onResume
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r == null) {
// We didn't actually resume the activity, so skipping any follow-up actions.
return;
}
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
...
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
performConfigurationChangedForActivity(r, r.newConfig);
if (DEBUG_CONFIGURATION) {
Slog.v(TAG, "Resuming activity " + r.activityInfo.name + " with newConfig "
+ r.activity.mCurrentConfig);
}
r.newConfig = null;
}
if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
WindowManager.LayoutParams l = r.window.getAttributes();
if ((l.softInputMode
& WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
!= forwardBit) {
l.softInputMode = (l.softInputMode
& (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
| forwardBit;
if (r.activity.mVisibleFromClient) {
ViewManager wm = a.getWindowManager();
View decor = r.window.getDecorView();
wm.updateViewLayout(decor, l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
//添加window、設置可見
r.activity.makeVisible();
}
}
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
handleResumeActivity主要做了以下事情:
- 調用生命週期:通過performResumeActivity方法,內部調用生命週期onStart、onResume方法
- 設置視圖可見:通過activity.makeVisible方法,添加window、設置可見。(所以視圖的真正可見是在onResume方法之後)
先來看第一點,生命週期的調用。即performResumeActivity方法:
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
final ActivityClientRecord r = mActivities.get(token);
...
try {
...
r.activity.performResume(r.startsNotResumed, reason);
...
}
...
return r;
}
調用了activity.performResume方法:
final void performResume(boolean followedByPause, String reason) {
dispatchActivityPreResumed();
//內部會走onStart
performRestart(true /* start */, reason);
...
// 走onResume
mInstrumentation.callActivityOnResume(this);
...
//這裏是走fragment的onResume
mFragments.dispatchResume();
mFragments.execPendingActions();
...
}
先調用了performRestart(),performRestart()又會調用performStart(),performStart()內部調用了mInstrumentation.callActivityOnStart(this),也就是Activity的onStart()方法了。
然後是mInstrumentation.callActivityOnResume,也就是Activity的onResume()方法了。到這裏啓動後的生命週期走完了。
再看第二點,設置視圖可見。即activity.makeVisible()方法:
//Activity
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
這裏把activity的頂級佈局mDecor通過windowManager.addView()方法,把視圖添加到window,並設置mDecor可見。到這裏視圖是真正可見了。值得注意的是,視圖的真正可見是在onResume方法之後的。
好了,到這裏就是真正創建完成並且可見了。
梳理成關係圖如下:
涉及的類梳理如下:
類名 | 作用 |
---|---|
ActivityThread | 應用的入口類,系統通過調用main函數,開啓消息循環隊列。ActivityThread所在線程被稱爲應用的主線程(UI線程) |
ApplicationThread | 是ActivityThread的內部類,繼承IApplicationThread.Stub,是一個IBinder,是ActiivtyThread和AMS通信的橋樑,AMS則通過代理調用此App進程的本地方法,運行在Binder線程池 |
H | 繼承Handler,在ActivityThread中初始化,即主線程Handler,用於主線程所有消息的處理。本片中主要用於把消息從Binder線程池切換到主線程 |
Intrumentation | 具有跟蹤application及activity生命週期的功能,用於監控app和系統的交互 |
ActivityManagerService | Android中最核心的服務之一,負責系統中四大組件的啓動、切換、調度及應用進程的管理和調度等工作,其職責與操作系統中的進程管理和調度模塊相類似,因此它在Android中非常重要,它本身也是一個Binder的實現類。 |
ActivityTaskManagerService | 管理activity及其容器(task, stacks, displays)的系統服務(Android10中新增,分擔了AMS的部分職責) |
ActivityStarter | 用於解釋如何啓動活動。該類收集所有邏輯,用於確定Intent和flag應如何轉換爲活動以及相關的任務和堆棧 |
ActivityStack | 用來管理系統所有的Activity,內部維護了Activity的所有狀態和Activity相關的列表等數據 |
ActivityStackSupervisor | 負責所有Activity棧的管理。AMS的stack管理主要有三個類,ActivityStackSupervisor,ActivityStack和TaskRecord |
ClientLifecycleManager | 客戶端生命週期執行請求管理 |
ClientTransaction | 是包含一系列的 待客戶端處理的事務 的容器,客戶端接收後取出事務並執行 |
LaunchActivityItem、ResumeActivityItem | 繼承ClientTransactionItem,客戶端要執行的事務信息,啓動activity |
以上就是一個 普通Activity 啓動的完整流程。
爲啥我說 “普通Activity” 呢?因爲你會發現,整個流程是從startActivity這個方法開始的,是我們在一個Activity裏面啓動另一個Activity的情況。那麼第一個Activity,即 根Activity 是如何啓動的呢?
另外還注意到,在ActivityStackSupervisor的startSpecificActivityLocked方法中,上面分析有提到,有個判斷條件if (wpc != null && wpc.hasThread()),意思是 是否啓動了應用進程,而我們只分析了已啓動應用進程的情況。那麼未啓動應用進程的情況就是根Activity的啓動了。下面就來了解根Activity的啓動,也可以理解爲應用程序的啓動過程。
三、根Activity的啓動—應用進程啓動
我們知道,想要啓動一個應用程序(App),需要點擊手機桌面的應用圖標。Android系統的桌面叫做Launcher,有以下作用:
- 作爲Android系統的啓動器,用於啓動應用程序。
- 作爲Android系統的桌面,用於顯示和管理應用程序的快捷圖標和其他桌面組件。
Launcher本身也是一個應用程序,它在啓動過程中會請求PackageManageService(系統的包管理服務)返回系統中已經安裝的app的信息,並將其用快捷圖標展示在桌面屏幕上,用戶可以點擊圖標啓動app。例如華爲手機的Launcher就是 “華爲桌面” 這個系統app。
3.1 應用進程的創建
當點擊app圖標後,Launcher會在桌面activity(此activity就叫Launcher)內調用startActivitySafely方法,startActivitySafely方法會調用startActivity方法。接下來的部分就和上面分析的 Activity啓動的發起 過程一致了,即通過IPC走到了ATMS,直到ActivityStackSupervisor的startSpecificActivityLocked方法中對應用進程是否存在的判斷。我們再次瞅瞅:
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
//有應用進程就啓動activity
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
knownToBeDead = true;
}
...
try {
if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
+ r.processName);
}
// Post message to start process to avoid possible deadlock of calling into AMS with the
// ATMS lock held.
// 上面的wpc != null && wpc.hasThread()不滿足的話,說明沒有進程,就會去創建進程
final Message msg = PooledLambda.obtainMessage(
ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
mService.mH.sendMessage(msg);
} finally {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
}
邏輯很清晰:有應用進程就啓動activity(普通activity),沒有就去創建進程(然後再啓動根activity)。
應用進程存在的判斷條件是:wpc != null && wpc.hasThread(),看下WindowProcessController的hasThread方法:
// The actual proc... may be null only if 'persistent' is true (in which case we are in the
// process of launching the app)
private IApplicationThread mThread;
boolean hasThread() {
return mThread != null;
}
前面已有說明,IApplicationThread是ApplicationThread在客戶端(app)在服務端(系統進程)的代理,這裏判斷 IApplicationThread不爲空 就代表進程已存在,爲啥這麼判斷呢?這裏先猜測,進程創建後,一定會有給IApplicationThread賦值的操作,這樣就符合這個邏輯了。我們繼續看,瞅瞅進程是如何創建的,以及創建後是否有給IApplicationThread賦值的操作。
使用ActivityTaskManagerService的mH(繼承handler)發送了一個消息,消息中第一個參數是ActivityManagerInternal::startProcess,ActivityManagerInternal的實現是AMS的內部類LocalService,LocalService的startProcess方法調用了AMS的startProcessLocked方法,那麼我們就看看AMS 的startProcessLocked方法,這裏應該就是創建進程了:
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
HostingRecord hostingRecord, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
null /* crashHandler */);
}
這裏調用了ProcessList.startProcessLocked方法,內部又多次調用了startProcessLocked不同的重載方法,最後走到startProcess方法:
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,
long startTime) {
try {
...
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkSlow(startTime, "startProcess: returned from zygote!");
return startResult;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
調用了Process.start方法,跟進看下:
public static ProcessStartResult start(@NonNull final String processClass,
@Nullable final String niceName,
int uid, int gid, @Nullable int[] gids,
int runtimeFlags,
int mountExternal,
int targetSdkVersion,
@Nullable String seInfo,
@NonNull String abi,
@Nullable String instructionSet,
@Nullable String appDataDir,
@Nullable String invokeWith,
@Nullable String packageName,
@Nullable String[] zygoteArgs) {
return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, packageName,
/*useUsapPool=*/ true, zygoteArgs);
}
ZYGOTE_PROCESS是用於保持與Zygote進程的通信狀態,發送socket請求與Zygote進程通信。Zygote進程是進程孵化器,用於創建進程。ZYGOTE_PROCESS的start就不再跟進去了,關於這塊知識可以參考《Android進階解密》第二章、第三章。我們只需要知道其內部:
- Zygote通過fork創建了一個進程
- 在新建的進程中創建Binder線程池(此進程就支持了Binder IPC)
- 最終是通過反射獲取到了ActivityThread類並執行了main方法
3.2 根Activity的啓動
在之前文章 Handler:Android消息機制--《Android開發藝術探索》閱讀筆記——第十章 中介紹主線程的消息機制時就介紹過ActivityThread的main方法,主要就是開啓了主線程的消息循環。
final H mH = new H();
public static void main(String[] args) {
...
//1、準備主線程的Looper
Looper.prepareMainLooper();
long startSeq = 0;
if (args != null) {
for (int i = args.length - 1; i >= 0; --i) {
if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
startSeq = Long.parseLong(
args[i].substring(PROC_START_SEQ_IDENT.length()));
}
}
}
//這裏實例化ActivityThread,也就實例化了上面的mH,就是handler。
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
//獲取handler
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
//主線程looper開啓
Looper.loop();
//因爲主線程的Looper是不能退出的,退出就無法接受事件了。一旦意外退出,會拋出異常
throw new RuntimeException("Main thread loop unexpectedly exited");
}
在這理,我們關注 這兩這行代碼:
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);
創建ActivityThread實例,同時會創建ApplicationThread實例,ApplicationThread實例是ActivityThread實例的屬性。然後調用了attach方法:
private void attach(boolean system, long startSeq) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
//把ApplicationThread實例關聯到AMS中
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
...
}
前面提到過這裏mgr就是AMS在客戶端的代理,所以mgr的attachApplication方法,就是IPC的走到AMS的attachApplication方法了:
public final void attachApplication(IApplicationThread thread, long startSeq) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid, callingUid, startSeq);
Binder.restoreCallingIdentity(origId);
}
}
attachApplicationLocked方法很長,這裏保留重要的幾點:
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid, int callingUid, long startSeq) {
...
//1、IPC操作,創建綁定Application
thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
null, null, null, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(app.getWindowProcessController().getConfiguration()),
app.compat, getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial, autofillOptions, contentCaptureOptions);
...
// 2、賦值IApplicationThread
app.makeActive(thread, mProcessStats);
...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
//3、通過ATMS啓動 根activity
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
}
AMS的attachApplicationLocked方法主要三件事:
- 調用IApplicationThread的bindApplication方法,IPC操作,創建綁定Application;
- 通過makeActive方法賦值IApplicationThread,即驗證了上面的猜測(創建進程後賦值);
- 通過ATMS啓動 根activity
先看makeActive方法:
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
...
thread = _thread;
mWindowProcessController.setThread(thread);
}
看到使用mWindowProcessController.setThread(thread)確實完成了IApplicationThread的賦值。這樣就可以依據IApplicationThread是否爲空判斷進程是否存在了。
再看創建綁定Application的過程:IApplicationThread的bindApplication方法實現是客戶端的ApplicationThread的bindApplication方法,它又使用H轉移到了ActivityThread的handleBindApplication方法(從Binder線程池轉移到主線程),看下handleBindApplication方法:
private void handleBindApplication(AppBindData data) {
...
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
appContext.getOpPackageName());
try {
//創建Instrumentation
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
}
...
final ComponentName component = new ComponentName(ii.packageName, ii.name);
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
...
//創建Application
app = data.info.makeApplication(data.restrictedBackupMode, null);
...
mInitialApplication = app;
try {
mInstrumentation.onCreate(data.instrumentationArgs);
}
...
try {
//內部調用Application的onCreate方法
mInstrumentation.callApplicationOnCreate(app);
}
...
}
主要就是創建Application,並且調用生命週期onCreate方法。你會發現在前面介紹的ActivityThread的performLaunchActivity方法中,也有同樣的操作,只不過會先判斷Application是否已存在。也就是說,正常情況下Application的初始化是在handleBindApplication方法中的,並且是創建進程後調用的。performLaunchActivity中只是做了一個檢測,異常情況Application不存在時纔會創建。
再來看 根activity 的啓動,回到上面AMS的attachApplicationLocked方法,調用了mAtmInternal.attachApplication方法,mAtmInternal是ActivityTaskManagerInternal實例,具體實現是在ActivityTaskManagerService的內部類LocalService,去看看:
//ActivityTaskManagerService#LocalService
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
return mRootActivityContainer.attachApplication(wpc);
}
}
mRootActivityContainer是RootActivityContainer實例,看下它的attachApplication方法:
boolean attachApplication(WindowProcessController app) throws RemoteException {
final String processName = app.mName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
final ActivityStack stack = display.getFocusedStack();
if (stack != null) {
stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
final ActivityRecord top = stack.topRunningActivityLocked();
final int size = mTmpActivityList.size();
for (int i = 0; i < size; i++) {
final ActivityRecord activity = mTmpActivityList.get(i);
if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
&& processName.equals(activity.processName)) {
try {
if (mStackSupervisor.realStartActivityLocked(activity, app,
top == activity /* andResume */, true /* checkConfig */)) {
didSomething = true;
}
}
...
}
}
}
}
if (!didSomething) {
ensureActivitiesVisible(null, 0, false /* preserve_windows */);
}
return didSomething;
}
遍歷activity棧,此時理論上應該只有一個根activity,然後調用mStackSupervisor.realStartActivityLocked方法,看到這裏我們知道了,這裏就開始走上面分析過的流程了,即使用ClientTransaction會跨進程交給客戶端,然後就是2.3、2.4兩個小節的內容。
嗯,到這裏根activity的啓動流程也分析完了。
我們發現,根activity的啓動前 需要創建應用進程,然後走到ActivityThread的main方法,開啓主線程循環,初始化並綁定Application、賦值IApplicationThread,最後真正的啓動過程和普通Activity是一致的。
上面的流程圖 補充 根activity的邏輯,完整關係如下:
總結
關於 普通Activity 啓動的流程的講解,我們分成了幾個階段:啓動的發起、AMS的管理、線程切換、啓動核心實現,知道了啓動過程經歷了兩次IPC,客戶端到AMS、AMS到客戶端,以及Activity創建和生命週期的執行。 然後又在此基礎上 補充的根activity的啓動:先創建應用進程,再綁定Application,最後真正啓動跟Activity。
本篇內容涉及大量知識點,結合 IPC、Handler、Window等相關知識,這樣可以對Android系統有更加完整的認識。
好了,今天就到這裏,歡迎留言討論~
歡迎關注我的公衆號