一張圖看懂Activity啟動流程 Activity啟動流程詳解
Activity啟動流程比較複雜, 涉及的類及程式碼都很多, 本文側重從整體流程描述這個過程,給出關鍵節點,儘量少的涉及程式碼細節。
啥也不說了,先上圖。
在看本文的內容時, 可以參照此圖片進行閱讀。
Activity的啟動過程主要會涉及五個程序:Launcher程序、System_server程序、當前的前臺程序、待啟動的Activity所在程序、Zygote程序, 在上圖中已有所體現。
本文主要以Launcher啟動APP的過程來分析。閱讀過程可能會比較漫長, 如果只是想了解Activity啟動的大致流程, 可以參流程圖,跳過一些細節,但千萬別放棄治療。。。
基礎介紹
1. Android的系統啟動過程中會執行這樣的一個邏輯:
>Zygote程序 --> System_Server程序(管理各種系統服務)--> 應用程序
2.Android程序間通訊Binder機制的簡單理解
Android特有的程序間通訊方式,可以簡單的理解為三部分 Binder Client, Binder Server, Binder driver。程序A和程序B之間通訊, 如程序A想向程序B發起請求操作, 則程序A需要定義一個
Binder Client, 程序B定義一個Binder Server, client端向server發起請求操作這個過程會由Binder driver來協助執行。如果有資料返回, server端執行完後會返回一個Parcel資料。舉一個簡單的例子, 程序A想呼叫程序B的functionB()方法, 則程序A通過 已建立的Binder Client向程序B發起請求, 程序B的 Binder Server收到請求後,就會執行functionB()方法,如果functionB()方法是有返回值的, 則Binder Server會把這個值返回給程序A。如果程序B也想向程序A發起請求操作, 則需要再在程序B中建立一個Binder client, 程序A中建立一個Binder server, 然後程序B的 client向 程序A的 server發起請求。例如 程序B想請求程序A的 functionA()方法, 則需要程序 B 的client向程序A的 server發起請求。
本文的重點不是Binder機制, 如果不是很理解,可以自行查詢下binder的相關資料,網上應該是多得用車都裝不完的。。。下面進入正題。
一、開始請求啟動Activity
啟動Activity通常是在我們的Activity中啟動另一個Activity, 或者在手機桌面點選App圖示,就啟動了我們的主Activity,但都是呼叫startActivity(intent)方法開始,下面介紹從Launcher啟動我們的主Activity。
@Override protected void onListItemClick(ListView l, View v, int position, long id) { Intent intent = intentForPosition(position); startActivity(intent); }
下面是方法呼叫鏈
Activity.startActivity()
Activity.startActivityForResult()
Instrumentation.execStartActivty()
ActivityManagerNative.getDefault().startActivityAsUser()
首先呼叫進Activity的startActivity()方法
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
然後在Activity中的startActivity方法體裡呼叫了startActivity的過載方法,這裡我們看一下其過載方法的實現:
@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);
}
}
由於在上一步驟中我們傳遞的Bunde物件為空,所以這裡我們執行的是else分支的邏輯,所以這裡呼叫了startActivityForResult方法,並且傳遞的引數為intent和-1.
額外收穫:Android的原始碼真是太精妙了,程式碼複用到了極致, 這裡呼叫startActivityForResult(), 由於我們本身沒有傳入requestCode, 這裡系統傳入了 -1,其實requestCode小於0都不會起作用的,可以實測一下, 具體原因我們接著分析。
我們接著往下看startActivityForResult方法的具體實現
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
if (mParent == null) {
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) {
// If this start is requesting a result, we can avoid making
// the activity visible until the result is received. Setting
// this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
// activity hidden during this time, to avoid flickering.
// This can only be done when a result is requested because
// that guarantees we will get information back when the
// activity is finished, no matter what happens to it.
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
// TODO Consider clearing/flushing other event sources and events for child windows.
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
// Note we want to go through this method for compatibility with
// existing applications that may have overridden it.
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
看到了吧, 這段程式碼裡有一個判斷
if (requestCode >= 0) {
mStartedActivity = true;
}
這裡就解釋了 requestCode 小於0 確實是不起作用的, 上一段程式碼裡, 我們主要看 mParent == null 這個分支就行了, mParent代表的是ActivityGroup, 最開始用來在一個介面中嵌入多個子Activity,但是在API13中已經廢棄了, Google推薦我們用Fragment來代替ActivityGroup。然後呼叫mInstrumentation.execStartActivity()方法,簡單解釋下這幾個引數:
this,為啟動Activity的物件;
contextThread,為Binder物件,是主程序的context物件;
token,也是一個Binder物件,指向了服務端一個ActivityRecord物件;
target,為啟動的Activity;
intent,啟動的Intent物件;
requestCode,請求碼;
options,引數;
接著看這個execStartActivity方法:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
...
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
int result = ActivityManagerNative.getDefault()
.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;
}
這個方法中主要呼叫ActivityManagerNative.getDefault().startActivity方法,這裡要注意了,ActivityManagerNative是個什麼東西呢, 跟進去看一下:
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;
}
};
這裡用到了Singleton, 這是個什麼東西,點開看看。。。臥槽,原來是android自帶的單例模式工具類, 以前都沒發現。。。
public abstract class Singleton<T> {
private T mInstance;
protected abstract T create();
public final T get() {
synchronized (this) {
if (mInstance == null) {
mInstance = create();
}
return mInstance;
}
}
}
接著我們剛剛的分析,注意這一行程式碼 IActivityManager am = asInterface(b);, 最終返回的是am, 點進去看看這個asInterface():
static public IActivityManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IActivityManager in =
(IActivityManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ActivityManagerProxy(obj);
}
看著程式碼,熟悉Binder的同學是不是有點明白了, 這不就是Binder嗎, 好了,要開始搞事情了, 肯定要跨程序通訊了。我們剛剛說到通過Binder機制通訊, 要在本地執行緒建立client,服務端程序建立Server。我們這裡要啟動一個Activity, 肯定要通知我們的System_Server程序吖, 這可是Android系統排程各種資源的核心程序。那就開始建立吧,於是在當前程序中建立一個本地代理ActivityManagerProxy,與System_server程序的 ActivityManagerService 進行互動, 這倆是一對兒。
可以看一下他們的原始碼, ActivityManagerProxy實現了IActivityManager介面, ActivityManagerService繼承自ActivityManagerNative, ActivityManagerNative同樣實現了IActivityManager介面,並且ActivityManagerNative是一個抽象類, 所以它的最終實現類就是ActivityManagerService。
我們接著剛剛的分析,呼叫ActivityManagerNative.getDefault().startActivity, 實際上就是呼叫ActivityManagerProxy.startActivity(), ActivityManagerProxy是ActivityManagerNative的一個內部類, 我們進去看一下:
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;
}
注意到這一行程式碼: mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0); 這就是開啟Binder通訊, 下面將進入System_Server程序, 當前程序的這個執行緒將掛起,等待Server端程序執行完畢。 我們進入ActivityManagerService去開看看這個被client端呼叫的startActivity()方法。
二、System_Server程序接收到啟動Activity的請求
先貼一下接下來的方法呼叫鏈
ActivityManagerService.startActivity()
ActvityiManagerService.startActivityAsUser()
ActivityStackSupervisor.startActivityMayWait()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.startActivityUncheckedLocked()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStackSupervisor.resumeTopActivityInnerLocked()
不要慌, 兄弟,不要慌, 放輕鬆, 我們一個一個往下看, 首先看一下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 options) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
啥都沒有,就調了一個方法, 接著往下看:
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, ALLOW_FULL_ONLY, "startActivity", null);
// TODO: Switch to user app stacks here.
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, false, userId, null, null);
}
這裡進行了一些關於userid的邏輯判斷,然後就呼叫mStackSupervisor.startActivityMayWait方法:
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
Bundle options, boolean ignoreTargetSecurity, int userId,
IActivityContainer iContainer, TaskRecord inTask) {
...
int res = startActivityLocked(caller, intent, resolvedType, aInfo,
voiceSession, voiceInteractor, resultTo, resultWho,
requestCode, callingPid, callingUid, callingPackage,
realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
componentSpecified, null, container, inTask);
...
return res;
}
這個方法中執行了啟動Activity的一些其他邏輯判斷,在經過判斷邏輯之後呼叫startActivityLocked方法:
final int startActivityLocked(IApplicationThread caller,
Intent intent, String resolvedType, ActivityInfo aInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode,
int callingPid, int callingUid, String callingPackage,
int realCallingPid, int realCallingUid, int startFlags, Bundle options,
boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
ActivityContainer container, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
...
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, this, container, options);
...
err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, true, options, inTask);
...
return err;
}
這個方法中構造了ActivityManagerService端的Activity物件–>ActivityRecord, 我們看一下ActivityRecord這個類的原始碼註釋
/**
* An entry in the history stack, representing an activity.
*/
final class ActivityRecord {
翻譯一下:存在歷史棧的一個例項,代表一個Activity。這就是ActivityManagerService中代表Activity的例項, 我們接著看呼叫的startActivityUncheckedLocked方法:
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
boolean doResume, Bundle options, TaskRecord inTask) {
...
ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
targetStack.mLastPausedActivity = null;
targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
if (!launchTaskBehind) {
// Don't set focus on an activity that's going to the back.
mService.setFocusedActivityLocked(r, "startedActivity");
}
return ActivityManager.START_SUCCESS;
}
startActivityUncheckedLocked方法中對Activity的啟動模式和對應的任務棧進行了判斷和處理,然後呼叫了startActivityLocked的過載方法:
final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
...
if (!newTask) {
// If starting in an existing task, find where that is...
...
}
...
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
這個方法裡對是否是一個新的任務棧Task進行了相關處理,儲存在windowManager服務中, 然後呼叫resumeTopActivitiesLocked方法:
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
if (targetStack == null) {
targetStack = mFocusedStack;
}
// Do targetStack first.
boolean result = false;
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (stack == targetStack) {
// Already started above.
continue;
}
if (isFrontStack(stack)) {
stack.resumeTopActivityLocked(null);
}
}
}
return result;
}
經過迴圈邏輯判斷之後,最終呼叫了resumeTopActivityLocked方法:
final boolean resumeTopActivityLocked(ActivityRecord prev) {
return resumeTopActivityLocked(prev, null);
}
繼續跟進程式碼:
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (mStackSupervisor.inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
mStackSupervisor.inResumeTopActivity = true;
if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
mService.updateSleepIfNeededLocked();
}
result = resumeTopActivityInnerLocked(prev, options);
} finally {
mStackSupervisor.inResumeTopActivity = false;
}
return result;
繼續呼叫resumeTopActivityInnerLocked方法:
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
...
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
} ...
return true;
}
經過一系列處理邏輯之後最終呼叫了startPausingLocked方法,這個方法作用就是讓系統中棧中的Activity執行onPause方法。
三、執行棧頂Activity的onPause方法
方法呼叫鏈:
ActivityStack.startPausingLocked()
IApplicationThread.schudulePauseActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage();
ActivityThread.H.handleMessage()
ActivityThread.handlePauseActivity()
ActivityThread.performPauseActivity()
Activity.performPause()
Activity.onPause()
ActivityManagerNative.getDefault().activityPaused(token)
ActivityManagerService.activityPaused()
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
ActivityStack.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopActivityInnerLocked()
ActivityStack.startSpecificActivityLocked()
不要被這麼多方法嚇到了, 主線已經比較清楚了, 從第一個方法看起:
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
...
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
} else {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
...
}
注意這一行程式碼:pre.app.thread.schedulePauseActivity(),這裡的thread是一個IApplicationThread型別的物件,實現這一介面的類只有ApplicationThreadNative,並且是一個抽象類還繼承了Binder, 所以這是一個Binder物件,然後繼承ApplicationThreadNative的有兩個類, 分別是 ActivityThread中的內部類ApplicationThread, 以及ApplicationThreadNative中的內部類 ApplicationThreadProxy,所以他們也都是Binder物件, 看見Binder, 我們就知道,肯定要搞事情了, 要跨程序傳輸了。有沒有似曾相識的感覺, 前面我們介紹ActivityManagerService時, 也是同樣的套路。
對比一下:
IActivityManager介面
ActivityManagerNative 唯一實現類, 抽象類
ActivityManagerService binder的服務端
ActivityManagerProxy binder的客戶端, ActivityManagerNative的內部類,
IApplicationThread介面
ApplicationThreadNative 唯一實現類, 抽象類
ApplicationThread binder服務端
ApplicationThreadProxy binder客戶端, ApplicationThreadNative的內部類
接著剛剛的程式碼看,pre.app.thread.schedulePauseActivity(), 這一行程式碼,schedulePauseActivity() 從這個方法的名我們大致可以看出, 這是一個執行onPause()的方法, 可是目前還在System_server程序中啊, 所以我們要通知當前的前臺應用程序,告訴它:你的Activity該執行onPause了。由於我們目的是要呼叫到當前前臺程序的方法, 所以這裡我們在當前程序即 System_Server程序建立Binder client端,即ApplicationThreadProxy, 然後向Binder server端, 即前臺程序的ApplicationThread 發起binder通訊。 這裡如果不是很理解的話, 可以先記憶下來, 這就是Binder通訊的套路。
所以這裡pre.app.thread.schedulePauseActivity()實際上就是呼叫ActivityManagerProxy.schedulePauseActivity()方法, 我們進去看一下
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInterfaceToken(IApplicationThread.descriptor);
data.writeStrongBinder(token);
data.writeInt(finished ? 1 : 0);
data.writeInt(userLeaving ? 1 :0);
data.writeInt(configChanges);
data.writeInt(dontReport ? 1 : 0);
mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
IBinder.FLAG_ONEWAY);
data.recycle();
}
可以看到, 這裡呼叫了mRemote.transac(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION,data, null,IBinder.FLAG_ONEWAY);這裡的mRemote就是一個Binder物件, 是一個服務端在本地的binder代理物件, 呼叫了transac()方法, 發起了Binder通訊。 接下來, 我們去服務端的ApplicationThread這個類看看:
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
configChanges);
}
這裡傳送了一個訊息, 點進去:
private void sendMessage(int what, Object obj, int arg1, int arg2) {
sendMessage(what, obj, arg1, arg2, 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方法,mH是在ActivityThread中的一個Handler物件,主要處理SystemServer程序的訊息,我們看一下其handleMessge方法的實現:
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
...
case PAUSE_ACTIVITY_FINISHING:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
(msg.arg1&1) != 0);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
}
發現其呼叫了handlePauseActivity方法:
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
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());
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
}
}
mSomeActivitiesChanged = true;
}
}
然後在方法體內部通過呼叫performPauseActivity方法來實現對棧頂Activity的onPause生命週期方法的回撥,可以具體看一下他的實現:
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState) : null;
}
然後呼叫其過載方法:
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
...
mInstrumentation.callActivityOnPause(r.activity);
...
return !r.activity.mFinished && saveState ? r.state : null;
}
這樣回到了mInstrumentation的callActivityOnPuase方法:
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
看見了吧, 看見了吧,進入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;
}
哈哈哈哈哈, 終於看到onPause()方法了!
特別注意: 面試的時候有時會問到類似的問題, Activity啟動另一個Activity, onPause()和 onCreate()誰先執行, 從這裡我們得知, 是onPause先得到執行。
回到我們剛剛的handlePauseActivity方法, 執行完上述程式碼後, 還執行了另一行重要程式碼:ActivityManagerNative.getDefault().activityPaused(token); 這個的作用就是告訴System_Server程序, 我前臺程序已執行完onPause()方法了, 你可以繼續往下執行了。 這裡同樣是跨程序binder通訊, 通過前面的分析, 我們知道最終會呼叫到System_server程序中的ActivityManagerService的activityPaused方法:
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
可以發現,該方法內部會呼叫ActivityStack的activityPausedLocked方法,好吧,繼續看一下activityPausedLocked方法的實現:
private void completePauseLocked(boolean resumeNext) {
...
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) {
mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
} else {
mStackSupervisor.checkReadyForSleepLocked();
ActivityRecord top = topStack.topRunningActivityLocked(null);
if (top == null || (prev != null && top != prev)) {
// If there are no more activities available to run,
// do resume anyway to start something. Also if the top
// activity on the stack is not the just paused activity,
// we need to go ahead and resume it to ensure we complete
// an in-flight app switch.
mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
}
}
}
...
}
經過了一系列的邏輯之後,又呼叫了resumeTopActivitiesLocked方法,又回到了第二步中解析的方法中了,這樣經過
resumeTopActivitiesLocked –>
ActivityStack.resumeTopActivityLocked() –>
resumeTopActivityInnerLocked() –>
startSpecificActivityLocked()
我們看一下startSpecificActivityLocked的具體實現:
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
ProcessRecord app = mService.getProcessRecordLocked(r.processName,
r.info.applicationInfo.uid, true);
r.task.stack.setLaunchTime(r);
if (app != null && app.thread != null) {
try {
if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
|| !"android".equals(r.info.packageName)) {
// Don't add this if it is a platform component that is marked
// to run in multiple processes, because this is actually
// part of the framework so doesn't make sense to track as a
// separate apk in the process.
app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
mService.mProcessStats);
}
realStartActivityLocked(r, app, 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.
}
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
可以發現在這個方法中,首先會判斷一下需要啟動的Activity所需要的應用程序是否已經啟動,若啟動的話,則直接呼叫realStartAtivityLocked方法,否則呼叫startProcessLocked方法,用於啟動應用程序。
這樣關於啟動Activity時的第三步驟就已經執行完成了,這裡主要是實現了對棧頂Activity執行onPause
方法,而這個方法首先判斷需要啟動的Activity所屬的程序是否已經啟動,若已經啟動則直接呼叫啟動Activity的方法,否則將先啟動Activity的應用程序,然後在啟動該Activity。
四、啟動Activity所屬程序
方法呼叫鏈:
ActivityManagerService.startProcessLocked()
Process.start()
ActivityThread.main()
ActivityThread.attach()
ActivityManagerNative.getDefault().attachApplication()
ActivityManagerService.attachApplication()
首先看一下startProcessLocked()方法的具體實現:
private final void startProcessLocked(ProcessRecord app,
String hostingType, String hostingNameStr) {
startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
null /* entryPoint */, null /* entryPointArgs */);
}
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
...
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
app.processName);
checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
...
}
從上述方法考單,經過一系列的初始化操作之後呼叫了Process.start方法,並且傳入了啟動的類名“android.app.ActivityThread”, 接著看start:
public static final ProcessStartResult start(final String processClass,
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
throw new RuntimeException(
"Starting VM process through Zygote failed", ex);
}
}
這裡呼叫了startViaZygote()方法:
private static ProcessStartResult startViaZygote(final String processClass,
final String niceName,
final int uid, final int gid,
final int[] gids,
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
String abi,
String instructionSet,
String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
...
return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}
這裡最終呼叫了zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); 進入這個zygoteSendArgsAndGetResult()方法, 發現並沒有太多操作,就是一些讀寫流, 最後反回了一個ProcessStartResult物件,見名知意,返回的是一個程序開啟結果物件。 所以我們進入openZygoteSocketIfNeeded(abi), 具體操作肯定在這裡:
/**
* Tries to open socket to Zygote process if not already open. If
* already open, does nothing. May block and retry.
*/
private static void openZygoteSocketIfNeeded()
throws ZygoteStartFailedEx {
int retryCount;
if (sPreviousZygoteOpenFailed) {
/*
* If we've failed before, expect that we'll fail again and
* don't pause for retries.
*/
retryCount = 0;
} else {
retryCount = 10;
}
/*
* See bug #811181: Sometimes runtime can make it up before zygote.
* Really, we'd like to do something better to avoid this condition,
* but for now just wait a bit...
*/
for (int retry = 0
; (sZygoteSocket == null) && (retry < (retryCount + 1))
; retry++ ) {
if (retry > 0) {
try {
Log.i("Zygote", "Zygote not up yet, sleeping...");
Thread.sleep(ZYGOTE_RETRY_MILLIS);
} catch (InterruptedException ex) {
// should never happen
}
}
try {
sZygoteSocket = new LocalSocket();
sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,
LocalSocketAddress.Namespace.RESERVED));
sZygoteInputStream
= new DataInputStream(sZygoteSocket.getInputStream());
sZygoteWriter =
new BufferedWriter(
new OutputStreamWriter(
sZygoteSocket.getOutputStream()),
256);
Log.i("Zygote", "Process: zygote socket opened");
sPreviousZygoteOpenFailed = false;
break;
} catch (IOException ex) {
......
}
}
......
}
在這裡面, 我們看到 sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET, LocalSocketAddress.Namespace.RESERVED)); 這裡實際上就是通過socket流與 Zygote程序進行通訊, 通知Zygote建立一個新的程序。這裡根據Android界人盡皆知的大神 老羅的原始碼分析, 最終這個Socket由frameworks/base/core/java/com/android/internal/os/ZygoteInit.java檔案中的ZygoteInit類在runSelectLoopMode函式偵聽到。 【注意】如果對這個過程不想細看,可以跳過,直接進入下一個緩解。這裡博主想進入到Zygote的身體裡面,去解讀一些不為人知的奧祕(微笑臉):
public class ZygoteInit {
......
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*
* @throws MethodAndArgsCaller in a child process when a main() should
* be executed.
*/
private static void runSelectLoopMode() throws MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList();
ArrayList<ZygoteConnection> peers = new ArrayList();
FileDescriptor[] fdArray = new FileDescriptor[4];
fds.add(sServerSocket.getFileDescriptor());
peers.add(null);
int loopCount = GC_LOOP_COUNT;
while (true) {
int index;
/*
* Call gc() before we block in select().
* It's work that has to be done anyway, and it's better
* to avoid making every child do it. It will also
* madvise() any free memory as a side-effect.
*
* Don't call it every time, because walking the entire
* heap is a lot of overhead to free a few hundred bytes.
*/
if (loopCount <= 0) {
gc();
loopCount = GC_LOOP_COUNT;
} else {
loopCount--;
}
try {
fdArray = fds.toArray(fdArray);
index = selectReadable(fdArray);
} catch (IOException ex) {
throw new RuntimeException("Error in select()", ex);
}
if (index < 0) {
throw new RuntimeException("Error in select()");
} else if (index == 0) {
ZygoteConnection newPeer = acceptCommandPeer();
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else {
boolean done;
done = peers.get(index).runOnce();
if (done) {
peers.remove(index);
fds.remove(index);
}
}
}
}
......
}
分析上述程式碼, 將資料通過Socket介面傳送出去後,就會執行這一行:
done = peers.get(index).runOnce();
這裡從peers.get(index)得到的是一個ZygoteConnection物件,表示一個Socket連線,因此,接下來就是呼叫ZygoteConnection.runOnce函式進一步處理了。
Step 6. ZygoteConnection.runOnce
這個函式定義在frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java檔案中:
class ZygoteConnection {
......
private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, PrintStream newStderr)
throws ZygoteInit.MethodAndArgsCaller {
......
if (parsedArgs.runtimeInit) {
RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
} else {
......
}
}
......
}
繼續看RuntimeInit.zygoteInit:
public static final void zygoteInit(String[] argv)
throws ZygoteInit.MethodAndArgsCaller {
// TODO: Doing this here works, but it seems kind of arbitrary. Find
// a better place. The goal is to set it up for applications, but not
// tools like am.
System.setOut(new AndroidPrintStream(Log.INFO, "System.out"));
System.setErr(new AndroidPrintStream(Log.WARN, "System.err"));
commonInit();
zygoteInitNative();
int curArg = 0;
for ( /* curArg */ ; curArg < argv.length; curArg++) {
String arg = argv[curArg];
if (arg.equals("--")) {
curArg++;
break;
} else if (!arg.startsWith("--")) {
break;
} else if (arg.startsWith("--nice-name=")) {
String niceName = arg.substring(arg.indexOf('=') + 1);
Process.setArgV0(niceName);
}
}
if (curArg == argv.length) {
Slog.e(TAG, "Missing classname argument to RuntimeInit!");
// let the process exit
return;
}
// Remaining arguments are passed to the start class's static main
String startClass = argv[curArg++];
String[] startArgs = new String[argv.length - curArg];
System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);
invokeStaticMain(startClass, startArgs);
}
這裡有兩個關鍵的函式呼叫,一個是zygoteInitNative函式呼叫,一個是invokeStaticMain函式呼叫,前者就是執行Binder驅動程式初始化的相關工作了,正是由於執行了這個工作,才使得程序中的Binder物件能夠順利地進行Binder程序間通訊,而後一個函式呼叫,就是執行程序的入口函式,這裡就是執行startClass類的main函數了,而這個startClass即是我們在Step 1中傳進來的”android.app.ActivityThread”值,表示要執行android.app.ActivityThread類的main函式。
臥槽, 是不是更加明白為啥ActivityThread叫主執行緒了吧, 一個程序的java啟動入口, 就是從這裡開始的。
好了, 這些我們真正的進入了我們待啟動Activity的程序身體裡面了, 看一下ActivityThread的main方法:
public static void main(String[] args) {
...
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
主要執行了一些初始化的邏輯,並且建立了一個UI執行緒訊息佇列,這也就是為什麼我們可以在主執行緒中隨意的建立Handler而不會報錯的原因, 這也是為啥我們在子執行緒建立訊息佇列的話,要呼叫Looper.prepare()方法了。
然後執行了ActivityThread的attach方法,這裡我們看一下attach方法:
private void attach(boolean system) {
...
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
// Ignore
}
...
}
又是老套路, 前面我們已經分析過了, 這裡會通過Binder呼叫System_server程序的ActivityManagerService的attachApplication(), 繼續看:
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
發現其回調了attachApplicationLocked方法:
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
...
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
...
return true;
}
該方法執行了一系列的初始化操作, 呼叫了 mStackSupervisor.attachApplicationLocked(app)。
為什麼我們待啟動Activity的程序已經啟動了, 還要進入System_server程序呢。 因為System_server程序管理了很多系統資源的排程, 所以我們真正啟動我們的Activity之前, 還要System_server程序中做一些操作, 當一切準備工作做好了, 就會通知應用程序, 你可以真正執行Activity的啟動了, 下面, 我們接著分析。
五、啟動Activity
呼叫方法鏈:
ActivityStackSupervisor.attachApplicationLocked()
ActivityStackSupervisor.realStartActivityLocked()
IApplicationThread.scheduleLauncherActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage()
ActivityThread.H.handleMessage()
ActivityThread.handleLauncherActivity()
ActivityThread.performLauncherActivity()
Instrumentation.callActivityOnCreate()
Activity.onCreate()
ActivityThread.handleResumeActivity()
ActivityThread.performResumeActivity()
Activity.performResume()
Instrumentation.callActivityOnResume()
Activity.onResume()
ActivityManagerNative.getDefault().activityResumed(token)
接著上面的分析, 先來看看attachApplicationLocked:
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
final String processName = app.processName;
boolean didSomething = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = stacks.get(stackNdx);
if (!isFrontStack(stack)) {
continue;
}
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ hr.intent.getComponent().flattenToShortString(), e);
throw e;
}
}
}
}
}
if (!didSomething) {
ensureActivitiesVisibleLocked(null, 0);
}
return didSomething;
其內部呼叫了realStartActivityLocked方法:
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
...
app.forceProcessStateUpTo(mService.mTopProcessState);
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
...
return true;
}
又來了, app.thread.scheduleLaunchActivity(), 前面已分析過, 又是Binder, 這裡最終呼叫的是我們待啟動Activity程序中的ActivityThread中的scheduleLauncherActivity, 好了, 我們再次進入待啟動Activity程序的身體:
public final void scheduleLaunchActivity(Intent intent, IBinder token, 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 notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
還是之前的邏輯,ActivityThread接收到System_Server程序的訊息之後會通過其內部的Handler物件分發訊息,經過一系列的分發之後最終呼叫了ActivityThread的handleLaunchActivity方法:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfiguration);
Bundle oldState = r.state;
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
}
...
}
這裡呼叫了performLauncherActivity,看名字應該就是執行Activity的啟動操作了:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.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) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
...
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
...
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
...
return activity;
}
可以發現這裡我們需要的Activity物件終於是創建出來了,而且他是以反射的機制建立的,這裡也體現了Android程式碼複用的精妙,這一整套程式碼都繫系統的, 但是具體的Activity類名,系統一開始不知道的,這裡傳進來類名, 通過反射即可擦混個建物件。
然後呼叫了mInstrumentation.callActivityOnCreate():
public void callActivityOnCreate(Activity activity, Bundle icicle,
PersistableBundle persistentState) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
然後activity.performCreate():
final void performCreate(Bundle icicle) {
onCreate(icicle);
mActivityTransitionState.readState(icicle);
performCreateCommon();
}
哈哈哈哈哈, 同志們,看見了吧, 生命週期方法onCreate()在這裡被呼叫了 。
按耐住激動的心情, 回到我們的performLaunchActivity方法中,其在呼叫了mInstrumentation.callActivityOnCreate方法之後又呼叫了activity.performStart()方法,看起來是呼叫onStart()方法的, 進去看一下:
final void performStart() {
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
mFragments.noteStateNotSaved();
mCalled = false;
mFragments.execPendingActions();
mInstrumentation.callActivityOnStart(this);
if (!mCalled) {
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onStart()");
}
mFragments.dispatchStart();
mFragments.reportLoaderStart();
mActivityTransitionState.enterReady(this);
}
又是通過Instrumentation呼叫callActivityOnStart方法:
public void callActivityOnStart(Activity activity) {
activity.onStart();
}
onStart方法也出現了~~~
再次回到剛剛的handleLaunchActivity方法,在呼叫完performLaunchActivity方法之後,其又呼叫了handleResumeActivity方法:
final void handleResumeActivity(IBinder token,
boolean clearHide, boolean isForward, boolean reallyResume) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
// TODO Push resumeArgs into the activity for consideration
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
...
// The window is now visible if it has been added, we are not
// simply finishing, and we are not starting another activity.
if (!r.activity.mFinished && willBeVisible
&& r.activity.mDecor != null && !r.hideForNow) {
if (r.newConfig != null) {
r.tmpConfig.setTo(r.newConfig);
if (r.overrideConfig != null) {
r.tmpConfig.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
+ r.activityInfo.name + " with newConfig " + r.tmpConfig);
performConfigurationChanged(r.activity, r.tmpConfig);
freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
r.newConfig = null;
}
}
...
// Tell the activity manager we have resumed.
if (reallyResume) {
try {
ActivityManagerNative.getDefault().activityResumed(token);
} catch (RemoteException ex) {
}
}
} else {
// If an exception was thrown when trying to resume, then
// just end this activity.
try {
ActivityManagerNative.getDefault()
.finishActivity(token, Activity.RESULT_CANCELED, null, false);
} catch (RemoteException ex) {
}
}
}
resumeActivity的邏輯呼叫到了performResumeActivity()方法,還看到了performConfigurationChanged(), 我們來重點關注下performResumeActivity:
final void performResume() {
...
mInstrumentation.callActivityOnResume(this);
...
}
都是老套路, 接著看 callActivityOnResume:
public void callActivityOnResume(Activity activity) {
activity.mResumed = true;
activity.onResume();
if (mActivityMonitors != null) {
synchronized (mSync) {
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
am.match(activity, activity, activity.getIntent());
}
}
}
}
onResume方法。。。它出現了~~~
這時候我們的介面應該已經展示出來了,我們的Activity應該已經啟動,但是完,我們的生命週期方法還沒走完:Activity a 啟動 Activity b 會觸發的生命週期方法:a的onPause方法和onStop方法,b的onCreate onStart方法,onResume方法, 現在, 就差 a的 onStop了
六、棧頂Activity執行onStop方法
繼續貼方法鏈:
Looper.myQueue().addIdleHandler(new Idler())
Idler.queueIdle()
ActivityManagerNative.getDefault().activityIdle()
ActivityManagerService.activityIdle()
ActivityStackSupervisor.activityIdleInternalLocked()
ActivityStack.stopActivityLocked()
IApplicationThread.scheduleStopActivity()
ActivityThread.scheduleStopActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage()
ActivityThread.H.handleMessage()
ActivityThread.handleStopActivity()
ActivityThread.performStopActivityInner()
ActivityThread.callCallActivityOnSaveInstanceState()
Instrumentation.callActivityOnSaveInstanceState()
Activity.performSaveInstanceState()
Activity.onSaveInstanceState()
Activity.performStop()
Instrumentation.callActivityOnStop()
Activity.onStop()
回到我們的handleResumeActivity方法,在方法體最後有這樣的一程式碼:
Looper.myQueue().addIdleHandler(new Idler());
點進去看一下:
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityManager am = ActivityManagerNative.getDefault();
ActivityClientRecord prev;
do {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
(a.activity != null && a.activity.mFinished));
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
// Ignore
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
ensureJitEnabled();
return false;
}
}
這樣當Messagequeue執行add方法之後就會回撥其queueIdle()方法,我們可以看到在方法體中其呼叫了ActivityManagerNative.getDefault().activityIdle(),好吧,熟悉了Binder機制以後我們知道這段程式碼會執行到ActivityManagerService的activityIdle方法:
public final void act