Activity啟動(dòng)流程
一、執(zhí)行startActivity
-
Activity.startActivity(Intent intent, @Nullable Bundle options)
@Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } }
-
Activity.startActivityForResult ------requestCode == -1
mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
“Instrumentation是啟動(dòng)Activity的操作類”指蚁,每一個(gè)應(yīng)用程序只有一個(gè)Instrumentation對(duì)象,每個(gè)Activity持有一個(gè)該對(duì)象的引用哎壳。包括了調(diào)用Activity的各生命周期方法的callActivityxxx()。
-
Instrumentation.execStartActivty
int result = ActivityManagerNative.getDefault() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);
getDefault()返回的是:
static public IActivityManager getDefault() { return gDefault.get(); }
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } };
asInterface{ .... return new ActivityManagerProxy(obj); }
ActivityManagerNative extends Binder
接口的實(shí)現(xiàn)關(guān)系:
? IInterface->IActivityManager–> ActivityManagerNative/ActivityManagerProxy
? ActivityManagerNative作為AMS的客戶端通過(guò)ActivityManagerProxy向AMS發(fā)送啟動(dòng)請(qǐng)求。
ActivityManagerService extends ActivityManagerNative
-
ActivityManagerProxy.startActivity()
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); data.writeStrongBinder(caller != null ? caller.asBinder() : null); data.writeString(callingPackage); intent.writeToParcel(data, 0); data.writeString(resolvedType); data.writeStrongBinder(resultTo); data.writeString(resultWho); data.writeInt(requestCode); data.writeInt(startFlags); if (profilerInfo != null) { data.writeInt(1); profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { data.writeInt(0); } if (options != null) { data.writeInt(1); options.writeToParcel(data, 0); } else { data.writeInt(0); } mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); reply.readException(); int result = reply.readInt(); reply.recycle(); data.recycle(); return result; }
通過(guò)binder向AMS傳輸數(shù)據(jù),AMS調(diào)用startActivity()方法
通過(guò)Binder向AMS發(fā)送啟動(dòng)Activity請(qǐng)求
二、ActivityManagerService接收啟動(dòng)Activity的請(qǐng)求烦租,并控制前臺(tái)Activity調(diào)用onPause
在AMSstartActivity()方法內(nèi)部,繼續(xù)調(diào)用startActivityAsUser()方法:
- ActivityManagerService.startActivity()
@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());
}
-
ActvityiManagerService.startActivityAsUser()
@Override public final 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 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, null, null, bOptions, false, userId, null, null); }
該方法返回時(shí)除盏,調(diào)用了ActivityStarter.startActivityMayWait()方法叉橱。
- ActivityStarter是一個(gè)專門負(fù)責(zé)Activity啟動(dòng)的控制類,通過(guò)intent和flag決定如何啟動(dòng)一個(gè)Activity者蠕,并關(guān)聯(lián)到Task和Stack窃祝。
ActivityStarter.startActivityMayWait()方法中,返回值如下:
-
ActivityStarter.startActivityMayWait()
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, container, inTask); ..... return res;
我們可以看到此處調(diào)用了ActivityStarter.startActivityLocked()方法踱侣,該方法關(guān)鍵部分如下:
-
ActivityStarter.startActivityLocked()
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, container, inTask); ···· return mLastStartActivityResult;
調(diào)用的startActivity()方法:
···· try { mService.mWindowManager.deferSurfaceLayout(); result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,startFlags, doResume, options, inTask, outActivity); } ···· return result;;
這里又調(diào)用了另一個(gè)方法ActivityStarter.startActivityUnchecked()粪小,在該方法中進(jìn)行了大量邏輯操作,這里挑出部分:
-
ActivityStarter.startActivityUnchecked()
···· final ActivityStack topStack = mSupervisor.mFocusedStack; final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop); ····
關(guān)于ActivityStackSupervisor抡句,它用來(lái)保存Activity的棧信息
- ActivityStackSupervisor
/** The stack containing the launcher app. Assumed to always be attached to * Display.DEFAULT_DISPLAY. */ ActivityStack mHomeStack; /** The stack currently receiving input or launching the next activity. */ ActivityStack mFocusedStack; /** If this is the same as mFocusedStack then the activity on the top of the focused stack has * been resumed. If stacks are changing position this will hold the old stack until the new * stack becomes resumed after which it will be set to mFocusedStack. */ private ActivityStack mLastFocusedStack;
mHomeStack : 只保存了 Launcher 的 Task;
mLastFocusedStack: 當(dāng)該值等于mFocusedStack探膊,代表當(dāng)前棧頂?shù)腁ctivity完成resume;
? 當(dāng)該值等于上一個(gè)舊棧時(shí)待榔,代表activity正在切換逞壁;
mIntent.setFlags(mLaunchFlags);//設(shè)置啟動(dòng)flag
mReusedActivity = getReusableIntentActivity();//決定是否將新的Activity插入到現(xiàn)有的task
····
final boolean dontStart = top != null && mStartActivity.resultTo == null
&& top.realActivity.equals(mStartActivity.realActivity)
&& top.userId == mStartActivity.userId
&& top.app != null && top.app.thread != null
&& ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask);
if (dontStart) {
ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
mSupervisor.resumeFocusedStackTopActivityLocked();
}
·····
return START_DELIVERED_TO_TOP;
}
·····
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);//啟動(dòng)Activity、是否開啟新task···
····
mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);//更新last used stack ID
····
-
ActivityStack.startActivityLocked()
···· TaskRecord rTask = r.task; final int taskId = rTask.taskId; // mLaunchTaskBehind tasks get placed at the back of the task stack. if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) { // Last activity in task had been removed or ActivityManagerService is reusing task. // Insert or replace. // Might not even be in. insertTaskAtTop(rTask, r); mWindowManager.moveTaskToTop(taskId); } TaskRecord task = null; if (!newTask) {//如果不是在新的Task中啟動(dòng)锐锣,就找出要運(yùn)行在TaskRecord的對(duì)象 // If starting in an existing task, find where that is... boolean startIt = true; for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { task = mTaskHistory.get(taskNdx); if (task.getTopActivity() == null) { // All activities in task are finishing. continue; } if (task == r.task) { // Here it is! Now, if this is not yet visible to the // user, then just add it without starting; it will // get started when the user navigates back to it. if (!startIt) { if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " + task, new RuntimeException("here").fillInStackTrace()); task.addActivityToTop(r); r.putInHistory(); addConfigOverride(r, task); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } ActivityOptions.abort(options); return; } break; } else if (task.numFullscreen > 0) { startIt = false; } } } // Place a new activity at top of stack, so it is next to interact // with the user. // If we are not placing the new activity frontmost, we do not want // to deliver the onUserLeaving callback to the actual frontmost // activity ······
-
ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()
boolean resumeFocusedStackTopActivityLocked( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) { if (targetStack != null && isFocusedStack(targetStack)) { return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); } final ActivityRecord r = mFocusedStack.topRunningActivityLocked(); if (r == null || r.state != RESUMED) { mFocusedStack.resumeTopActivityUncheckedLocked(null, null); } return false; }
-
ActivityStack.resumeTopActivityUncheckedLocked()
···· result = resumeTopActivityInnerLocked(prev, options); ···· return result;
這里主要調(diào)用了mSupervisor.resumeFocusedStackTopActivityLocked()方法腌闯,該方法繼續(xù)調(diào)用targetStack.resumeTopActivityUncheckedLocked(target, targetOptions),在
resumeTopActivityUncheckedLocked方法中刺下,繼續(xù)調(diào)用resumeTopActivityInnerLocked(prev, options)并返回绑嘹。resumeTopActivityInnerLocked方法關(guān)鍵邏輯如下:
-
ActivityStack.resumeTopActivityInnerLocked()
···· /** * Current activity that is resumed, or null if there is none. */ ActivityRecord mResumedActivity = null; ···· //找出還沒(méi)結(jié)束的首個(gè)ActivityRecord ActivityRecord next = topRunningActivityLocked(null); ···· boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause); ···· //啟動(dòng)前需要暫停前一個(gè)Activity if (mResumedActivity != null) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause); }
此時(shí),開始進(jìn)入pause階段橘茉,調(diào)用ActivityStack.startPausingLocked()方法芯丧,這里截取主要部分:
-
ActivityStack.startPausingLocked()
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) { if (mPausingActivity != null) { completePauseLocked(false); } ..... ActivityRecord prev = mResumedActivity; ····· if (prev.app != null && prev.app.thread != null) try { mService.updateUsageStats(prev, false); prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing, userLeaving, prev.configChangeFlags, dontWait); } catch (Exception e) { mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; } } else { mPausingActivity = null; mLastPausedActivity = null; mLastNoHistoryActivity = null; } ..... }
這里映跟,prev.app為記錄啟動(dòng)Lancher進(jìn)程的ProcessRecord,prev.app.thread為L(zhǎng)ancher進(jìn)程的遠(yuǎn)程調(diào)用接口IApplicationThead莹弊,調(diào)用prev.app.thread.schedulePauseActivity蟋恬,在Lancher進(jìn)程中消息傳
遞翁潘,調(diào)用ActivityThread.handlePauseActivity(),最終調(diào)用ActivityThread.performPauseActivity()暫停指定Activity歼争。
ActivityThread.schedulePauseActivity()中發(fā)送了一個(gè)Message拜马,方法如下:
ActivityThread.schedulePauseActivity()
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
if (DEBUG_ORDER) Slog.d(TAG, "pauseActivity " + ActivityThread.this
+ " operation received seq: " + seq);
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
在handleMessage的PAUSE_ACTIVITY/PAUSE_ACTIVITY_FINISHING case中均調(diào)用了handlePauseActivity方法:
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
ActivityClientRecord r = mActivities.get(token);
if (DEBUG_ORDER) Slog.d(TAG, "handlePauseActivity " + r + ", seq: " + seq);
if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
return;
}
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
if (!dontReport) { //利用ActivityManagerNative通知ActivityThread已經(jīng)完成pause
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
該方法內(nèi)渗勘,調(diào)用了performPauseActivityIfNeeded()方法,在該方法中主要執(zhí)行的是performPauseActivityIfNeeded()方法完成pause俩莽,這里我們看一下performPauseActivityIfNeeded方法的具體實(shí)現(xiàn):
private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
if (r.paused) {
// You are already paused silly...
return;
}
try {
r.activity.mCalled = false;
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_AM_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName(), reason);
if (!r.activity.mCalled) {
throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
+ " did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException("Unable to pause activity "
+ safeToComponentShortString(r.intent) + ": " + e.toString(), e);
}
}
r.paused = true;
}
該方法中旺坠,主要調(diào)用了mInstrumentation.callActivityOnPause(r.activity) 來(lái)執(zhí)行目標(biāo)Activity的onPause方法。前面已經(jīng)說(shuō)過(guò)扮超,“Instrumentation是啟動(dòng)Activity的操作類”取刃,它的callActivityOnPause()如下,Activity.performPause()方法中我們可以看到的確調(diào)用了onPause()方法出刷。
/**
* Perform calling of an activity's {@link Activity#onPause} method. The
* default implementation simply calls through to that method.
*
* @param activity The activity being paused.
*/
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
final void performPause() {
mDoReportFullyDrawn = false;
mFragments.dispatchPause();
mCalled = false;
onPause();
mResumed = false;
if (!mCalled && getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.GINGERBREAD) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPause()");
}
mResumed = false;
}
以上完成了執(zhí)行onPause的過(guò)程璧疗,然后在handlePauseActivity()方法中,繼續(xù)調(diào)用ActivityManagerNative.getDefault().activityPaused()方法馁龟,向AMS通知onPause過(guò)程已完成崩侠。
ActivityThread中schedulePauseActivity()發(fā)送Message后,處理消息邏輯整理如下:
handlePauseActivity-performPauseActivity-performPauseActivityIfNeeded //具體執(zhí)行目標(biāo) | Activity的onpause方法
ActivityManagerNative
|
|—>ActivityMangerProxy—>activityPaused //ActivityMangerProxy通知ActivityThread
|
|—>AMS
ActivityManagerProxy.activityPaused()
public void activityPaused(IBinder token) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
ActivityManagerService接收到應(yīng)用進(jìn)程創(chuàng)建Activity的請(qǐng)求之后會(huì)執(zhí)行初始化操作坷檩,解析啟動(dòng)模式啦膜,處理信息等一系列操作。ActivityManagerService保存完請(qǐng)求信息之后會(huì)將當(dāng)前系統(tǒng)棧頂?shù)腁ctivity執(zhí)行onPause操作淌喻。
AMS.activityPaused
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);//獲取的當(dāng)前Activity的task的所在棧
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
ActivityStack.activityPausedLocked
if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
completePauseLocked(true, null);
return;
}
- Question:
3.任務(wù)棧由誰(shuí)管理僧家,存放在什么地方?
4.啟動(dòng)一個(gè)activity都是在主線程中執(zhí)行的嗎裸删?
5.AMS什么時(shí)候介入工作的八拱?
6.Binder客戶端是怎么和服務(wù)端通信的?
7.asinterface含義是什么涯塔?
8.整個(gè)過(guò)程由哪些成員協(xié)助完成肌稻?
9.他們都起到什么作用?
10.如何圖解全過(guò)程匕荸?