概述
話說Android中有四大組件:Activity、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系統有更深層次的理解,也會學習到系統源碼優秀的設計。並且對解決一些高級問題和深入的性能優化問題有很大幫助,是技術進階的必要階段。這就需要我們通過閱讀源碼來梳理這些問題,但另一方面,系統源碼是很龐大繁雜的,我們需要帶着問題抓住主流程,不能陷入代碼細節——這是閱讀系統源碼以及其他第三方庫源碼的正確姿勢。
流程分析
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 = ActivityManager.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的啓動又交給了ActivityManager.getService(),這是啥?跟進去看看:
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
看到這裏你應該明白了:這裏是獲取一個跨進程的服務。然後我們看下著名的ActivityManagerService類
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
ActivityManagerService繼承IActivityManager.Stub,實際也就是繼承了Binder並且實現了IActivityManager這個Binder接口,AMS也就是一個Binder,是IActivityManager的集體實現。所以ActivityManager.getService()獲取的Binder對象,具體實現是ActivityManagerService(AMS),並且是通過單例提供服務的。
然後ActivityManager.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中註冊就會有這個錯誤。
Activity的管理——AMS
好了,到這裏,Activity的啓動就轉移到系統進程提供的服務AMS中了,接着看AMS的startActivity:
@Override
public int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return mActivityTaskManager.startActivity(caller, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions);
}
AMS把啓動轉移到了ActivityTaskManagerService(ATMS)中了,ATMS用於管理Activity及其容器(任務、堆棧、顯示等)的系統服務。接着看:
//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方法,startActivityUnchecked內部調用了ActivityStack的startActivityLocked方法,startActivityLocked內部調用ensureActivitiesVisibleLocked方法,ensureActivitiesVisibleLocked又調用makeVisibleAndRestartIfNeeded方法,來看下:
private boolean makeVisibleAndRestartIfNeeded(ActivityRecord starting, int configChanges,
boolean isTop, boolean andResume, ActivityRecord r) {
// We need to make sure the app is running if it's the top, or it is just made visible from
// invisible. If the app is already visible, it must have died while it was visible. In this
// case, we'll show the dead window but will not restart the app. Otherwise we could end up
// thrashing.
if (isTop || !r.visible) {
// This activity needs to be visible, but isn't even running...
// get it started and resume if no other stack in this stack is resumed.
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Start and freeze screen for " + r);
if (r != starting) {
r.startFreezingScreenLocked(r.app, configChanges);
}
if (!r.visible || r.mLaunchTaskBehind) {
if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY, "Starting and making visible: " + r);
r.setVisible(true);
}
if (r != starting) {
// We should not resume activities that being launched behind because these
// activities are actually behind other fullscreen activities, but still required
// to be visible (such as performing Recents animation).
mStackSupervisor.startSpecificActivityLocked(r, andResume && !r.mLaunchTaskBehind,
true /* checkConfig */);
return true;
}
}
return false;
}
看到最後調用了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);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
}
...
}
接着調用了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是包含一系列的message的容器,message用於 發送到客戶端,包含回調方法和生命週期狀態。
接着看,使用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的操作從客戶端 跨進程 轉移到 AMS,AMS通過ActivityTaskManagerService、ActivityStarter、ActivityStack、ActivityStackSupervisor 對 Activity任務、activity棧、Activity記錄 管理後,又用過跨進程把正在啓動過程又轉移到了客戶端。
線程切換及消息處理——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;
@UnsupportedAppUsage
public static final int STOP_SERVICE = 116;
public static final int CONFIGURATION_CHANGED = 118;
...
@UnsupportedAppUsage
public static final int BIND_SERVICE = 121;
@UnsupportedAppUsage
public static final int UNBIND_SERVICE = 122;
...
public static final int EXECUTE_TRANSACTION = 159;
public static final int RELAUNCH_ACTIVITY = 160;
public static final int PURGE_RESOURCES = 161;
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 UNBIND_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
handleUnbindService((BindServiceData)msg.obj);
schedulePurgeIdler();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case SERVICE_ARGS:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceStart: " + String.valueOf(msg.obj)));
handleServiceArgs((ServiceArgsData)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case STOP_SERVICE:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
handleStopService((IBinder)msg.obj);
schedulePurgeIdler();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case CONFIGURATION_CHANGED:
handleConfigurationChanged((Configuration) msg.obj);
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();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
case RELAUNCH_ACTIVITY:
handleRelaunchActivityLocally((IBinder) msg.obj);
break;
case PURGE_RESOURCES:
schedulePurgeIdler();
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方法。
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方法之後)
好了,到這裏就是真正創建完成並且可見了。
總結
關於Activity啓動的流程的講解,我們分成了幾個階段:啓動的發起、AMS的管理、線程切換、啓動核心實現,知道了啓動過程經歷了兩次IPC,客戶端到AMS、AMS到客戶端,以及Activity創建和生命週期的執行。
好了,今天就到這裏,歡迎留言討論~
歡迎關注我的公衆號