前言
? 我還記得上個(gè)學(xué)期意外看到一篇文章,是凱子哥的一篇博客,講的是app第一個(gè)activity啟動(dòng)的底層過(guò)程(java),我當(dāng)時(shí)幾乎沒(méi)接觸過(guò)這塊的源碼,好像看了一半就放棄。還有一次刷知乎,看到一個(gè)人回答為什么ActivityThread里面Loop不會(huì)造成ANR,但是也是一臉萌比。這個(gè)學(xué)期開(kāi)始刷藝術(shù)探索,已經(jīng)看完了第十章,每一章都對(duì)著源碼自己又看了一遍,再加上之前對(duì)Binder,IPC的淺顯的研究。今天重新再來(lái)看這篇文章[【凱子哥帶你學(xué)Framework】Activity啟動(dòng)過(guò)程全解析],發(fā)現(xiàn)基本上是看小說(shuō)一樣的輕松看完了。。這是一種進(jìn)步!!感覺(jué)挺好的。感謝大神的知識(shí)分享,下面我用自己的方式來(lái)總結(jié)一下Activity啟動(dòng)的過(guò)程,但是我跟凱子哥不同,他講的那個(gè)其實(shí)就多了一點(diǎn)Launcher和applicaiton創(chuàng)建的知識(shí)。
? 說(shuō)一點(diǎn)自己的學(xué)習(xí)感受。首先:
- 源碼海洋里面不要太追求了解每一個(gè)細(xì)節(jié),不然分分鐘迷失自我。
- 有些知識(shí)是需要有其他知識(shí)儲(chǔ)備才能理解的。所以看不懂的時(shí)候放一放,過(guò)一段時(shí)間再來(lái)看。比如binder設(shè)計(jì)原理那塊我就留了一半。。因?yàn)楹蟀氩糠钟悬c(diǎn)看不太懂了,涉及到了C草。
- 看書(shū)上的源碼遠(yuǎn)遠(yuǎn)不夠,一定一定要自己去獨(dú)立的看一遍,自己去把整個(gè)流程過(guò)一遍。
- 畫(huà)草圖,流程圖。因?yàn)檫^(guò)程異常的復(fù)雜,在不同的類(lèi)里面調(diào)來(lái)調(diào)用,又臭又長(zhǎng)的調(diào)用鏈。
- 永遠(yuǎn)不要放棄,靜下心來(lái)研究,一切都不是問(wèn)題。
知識(shí)儲(chǔ)備
Binder, IPC機(jī)制??梢钥纯次抑暗膬善恼?a target="_blank" rel="nofollow">Android-IPC系列(一)Android-IPC系列(二) 。還有幾篇我覺(jué)得寫(xiě)的非常好的文章Android Binder設(shè)計(jì)與實(shí)現(xiàn) - 設(shè)計(jì)篇 Android進(jìn)程間通信(IPC)機(jī)制Binder簡(jiǎn)要介紹和學(xué)習(xí)計(jì)劃 。(這兩篇講的都比較深)看到藝術(shù)探索后面我終于知道為什么binder要在第二章就講解了。因?yàn)锽inder在后面幾乎是無(wú)處不在!
ActivityManagerService。本質(zhì)就是一個(gè)Binder,并且實(shí)體在服務(wù)端。AMS在遠(yuǎn)端操作著activity的生命周期。這個(gè)進(jìn)程由SystemServer進(jìn)程fork出來(lái)。
ActivityThread。大家都知道ActivityThread就是應(yīng)用的UI線程,main方法就是整個(gè)應(yīng)用的入口。ActivityThread本質(zhì)并不是一個(gè)線程,他只是依附著主線程存在。ActivityThread通過(guò)和AMS進(jìn)行IPC通信來(lái)共同管理Activity的生命周期。在后面我準(zhǔn)備寫(xiě)一篇關(guān)于Handle的續(xù)篇,里面還會(huì)提到他,因?yàn)橹骶€程里面的Looper就是在這里init的。
ApplicationThread.。它是ActivityThread的內(nèi)部類(lèi),本質(zhì)上ActivityThread是通過(guò)它來(lái)進(jìn)行和AMS的IPC通信的。它的本質(zhì)也是一個(gè)Binder!只不過(guò)這次他的實(shí)體放在客戶(hù)端,AMS通過(guò)他的代理類(lèi)ApplicationThreadProxy來(lái)和ApplicationThread通信。
Instrumentation.。這個(gè)類(lèi)我在看完第一遍書(shū)的時(shí)候感覺(jué)操作調(diào)用鏈里面的最外層。因?yàn)樽詈笠徊紸ctivity實(shí)例對(duì)象的生成和onCreat()方法的調(diào)用最終是來(lái)自這個(gè)類(lèi)的。其實(shí)這個(gè)類(lèi)是ActivityThread想要進(jìn)行的操作的具體操作類(lèi)。這個(gè)類(lèi)是全局的,并且每個(gè)acitivity里面都擁有一個(gè)它的引用。
ActivityStack(AMS中)。很好懂,一個(gè)activity棧。但是這個(gè)ActivityStack是有兩種類(lèi)型的,一種叫系統(tǒng)ActivityStack(HomeTask),這一類(lèi)的ActivityStack包含著Launcher(或者有其他我不知道的),還有一種是普通應(yīng)用的ActivityStack(安卓中Task這個(gè)概念的具體實(shí)現(xiàn)形式),其實(shí)就是一個(gè)Task(任務(wù)棧)。這個(gè)類(lèi)是由AMS來(lái)管理,AMS通過(guò)這個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)得知activity的狀態(tài)。
ActivityStackSuperisor(AMS中)。加了一個(gè)單詞,就是activity棧的管理者。這個(gè)類(lèi)的作用就是管理?xiàng)?,并且通過(guò)ActivityStack來(lái)獲得要啟動(dòng)的activity的信息。
ActivityRecord。這個(gè)就是上面說(shuō)的服務(wù)端的actiivty信息的載體類(lèi)。并且也是服務(wù)端的類(lèi)~這個(gè)類(lèi)相當(dāng)?shù)闹匾?,自始至終都貫穿在調(diào)用鏈里面,在安卓ActivityStack里面存儲(chǔ)的并不是activity實(shí)例,其實(shí)就是這個(gè)ActivityRecord的實(shí)例。
ActivityClientRecord。這個(gè)和上面區(qū)別就是這個(gè)類(lèi)是客戶(hù)端activity信息的載體類(lèi)。
-
TaskRecord。同樣,這個(gè)類(lèi)就是ActivityTask的信息記錄類(lèi)而已。
?好了,我覺(jué)得需要好好了解的幾個(gè)最核心的類(lèi)就是這幾個(gè)了,大家若不清楚,可以自己去源碼里面看,如果我有說(shuō)錯(cuò)的也請(qǐng)?jiān)?。。。其?shí)還有很多概念我在binder那篇文章里面講的不少了!這里算是又一次的補(bǔ)充吧。
Activity啟動(dòng)的流程
? 源碼之旅開(kāi)始??瓶?
1.Activity.startActivity(Intent intent)這個(gè)我們天天都在寫(xiě),好,去看源碼!
@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);
}
}
嗯,繼續(xù)看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());
}
...省略代碼
}
直接調(diào)用了Instrumentation去調(diào)用execStartActivity()方法。后面的調(diào)用先不管,直接去看execStartActivity()方法。需要注意的是mMainThread.getApplicationThread()就是通過(guò)ActivityThread去獲得了一個(gè)ApplicaitonThread實(shí)例
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
...省略代碼
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess();
//通過(guò)AMS啟動(dòng)了
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//用來(lái)檢測(cè)這個(gè)activity啟動(dòng)的結(jié)果,具體可以去查看源碼
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
}
return null;
}
看到這里發(fā)現(xiàn)它又用了個(gè)什么玩意調(diào)用了startActivity()方法,這是什么呢?這里的ActivityManagerNative.getDefault()就是我們期待了很久的ActivityManagerService的代理類(lèi)!如果你很清楚Binder的實(shí)現(xiàn),這個(gè)應(yīng)該難不倒你吧!AMS和代理類(lèi)本質(zhì)上都是IActivityManager的實(shí)現(xiàn)類(lèi)。(IAcitivtyManager,其實(shí)就是一個(gè)AIDL接口,不信自己去看源碼)。我給你看看getDefault()方法的實(shí)現(xiàn):
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;
}
};
就是這么簡(jiǎn)單!如果看到這里你看不懂了,建議你再回去看看Binder。接下來(lái)我們就可以繼續(xù)看AMS中startActivity()方法的實(shí)現(xiàn)了:注意,從這里開(kāi)始,調(diào)用鏈會(huì)變得很復(fù)雜
@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) {
//調(diào)用了startActivityAsUser,caller是我們的ApplicaitonThread
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, options,
UserHandle.getCallingUserId());
}
繼續(xù)看這個(gè)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 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.轉(zhuǎn)換app里面的activity棧,caller是我們的ApplicaitonThread
return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, options, userId, null, null);
}
? 發(fā)現(xiàn)調(diào)用了之前提到的ActivityStackSupervisor的startActivityMayWait()方法。這里的目的就是想去通過(guò)棧的管理者來(lái)通過(guò)傳進(jìn)來(lái)的數(shù)據(jù)去改變棧,并且拿到被啟動(dòng)activity的ActivityRecord實(shí)例。
? 在startActivityMayWait()里面,主要做了ActivityStack, ActivityInfo, LaunchMode等等各種信息的初始化工作,然后就又調(diào)用了startActivityLocked()方法, 這個(gè)方法里面又做了一系列的變量初始化,初始啟動(dòng)的錯(cuò)誤判斷, uid檢查之后,又調(diào)用了startActivityUncheckedLocked()方法。這個(gè)方法里面根據(jù)前面一系列的工作,確定了最終的LanuchMode,這個(gè)LaunchMode會(huì)在后面的函數(shù)被拿來(lái)進(jìn)行判斷,構(gòu)建了一個(gè)新的intent,ActivityInfo,ActivityTask。反正過(guò)程都TM又臭又長(zhǎng),細(xì)看下去一天就耗完了。接下來(lái)我們可以看到最終調(diào)用targetStack.resumeTopActivityLocked()方法。這個(gè)targetStack就是新的activity所要放入的Task的位置。也就是說(shuō),現(xiàn)在又要轉(zhuǎn)到ActivityTask中去看源碼了,科科!
? 注意的是,LaunchMode和ActivityStack的選擇是個(gè)很復(fù)雜的過(guò)程。我推薦一篇文章以及安卓的官方文檔鏈接。官方文檔,頓文的博客
? 需要非常注意的是,這個(gè)函數(shù)執(zhí)行的時(shí)候,被啟動(dòng)的activity里面被添加到棧里面去了,top,next就是指代這個(gè)要被啟動(dòng)的activity。pre,current就是指代當(dāng)前resumed的activity。你別弄混了,雖然這個(gè)問(wèn)題我TM看了一整天的源碼。注意,被啟動(dòng)的activity雖然還沒(méi)有被實(shí)例,但是它的ActivityRecord實(shí)例已經(jīng)被構(gòu)建出來(lái)了,并且已經(jīng)被添加到stack里面去了。具體的調(diào)用過(guò)程是:
? Supervisor.setActivityUnchekedLocked->resumeTopActivityLocked(這里是ActivityStackSuperbisor里面的方法)->ActivityStack.startActivityLocked在這里將activity添加到stack里面。并且在之后才會(huì)調(diào)用ActivityStack的resumeTopActivityLocked方法
/**
* Ensure that the top activity in the stack is resumed.
*
* @param prev The previously resumed activity, for when in the process
* of pausing; can be null to call from elsewhere.
*
* @return Returns true if something is being resumed, or false if
* nothing happened.
*/
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
if (inResumeTopActivity) {
// Don't even start recursing.
return false;
}
boolean result = false;
try {
// Protect against recursion.
inResumeTopActivity = true;
result = resumeTopActivityInnerLocked(prev, options);
} finally {
inResumeTopActivity = false;
}
return result;
}
?
? 不要有情緒,繼續(xù)看resumeTopActivityInnerLocked(prev, options);這個(gè)方法太長(zhǎng)了,我分析了一整天,終于所有體會(huì)吧。這個(gè)方法最終的作用是將啟動(dòng)者activity的生命周期變成paused,這樣之后被啟動(dòng)的activity的實(shí)例創(chuàng)建了之后才能順利的resumed。我們來(lái)看部分代碼:
// Find the first activity that is not finishing.
//找出棧頂中第一個(gè)沒(méi)有在被finish的activity,既我們要啟動(dòng)的actiivty
ActivityRecord next = topRunningActivityLocked(null);
// Remember how we'll process this pause/resume situation, and ensure
// that the state is reset however we wind up proceeding.
final boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
final TaskRecord prevTask = prev != null ? prev.task : null;
//如果整個(gè)stack里面是空的,那么直接啟動(dòng)launcher
if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on home display
final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
//直接resume系統(tǒng)ActivityStack里面的根activity(Launcher)
return isOnHomeDisplay() &&
mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
}
? 在這里,next這個(gè)變量很關(guān)鍵。它的注釋說(shuō)的是第一個(gè)沒(méi)有正在被銷(xiāo)毀的activity,顯然我們要被啟動(dòng)的activity符合這個(gè)條件。并且如果這個(gè)應(yīng)用級(jí)別的stack是空的,也就是說(shuō)現(xiàn)在應(yīng)該跳轉(zhuǎn)到系統(tǒng)級(jí)別的stack去,也就是顯示系統(tǒng)桌面。
// If the top activity is the resumed one, nothing to do.
//如果被啟動(dòng)的activity就是當(dāng)前處理Resumed狀態(tài)的activity的話,就什么不做。(一個(gè)activity啟動(dòng)自己就是這種情況)
if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
mStackSupervisor.allResumedActivitiesComplete()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next);
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Make sure to notify Keyguard as well if it is waiting for an activity to be drawn.
mStackSupervisor.notifyActivityDrawnForKeyguard();
return false;
}
?
? 我注釋說(shuō)的很清楚了,如果要啟動(dòng)的activity已經(jīng)是resumed了,就什么都不做。因?yàn)檫@就是一個(gè)當(dāng)前resumed的activity啟動(dòng)它自己。
// If we are sleeping, and there is no resumed activity, and the top
// activity is paused, well that is the state we want.
//如果系統(tǒng)正在休眠,并且當(dāng)前最上層的activity都已經(jīng)是paused狀態(tài)了(top activity就是我們要啟動(dòng)的activity)。那就是完美的狀態(tài)。
if (mService.isSleepingOrShuttingDown()
&& mLastPausedActivity == next
&& mStackSupervisor.allPausedActivitiesComplete()) {
// Make sure we have executed any pending transitions, since there
// should be nothing left to do at this point.
mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Going to sleep and all paused");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
? 如果系統(tǒng)正在休眠,并且當(dāng)前最上層的activity都已經(jīng)是paused狀態(tài)了(top activity就是我們要啟動(dòng)的activity)。那就是完美的狀態(tài)。
// If we are currently pausing an activity, then don't do anything
// until that is done.
if (!mStackSupervisor.allPausedActivitiesComplete()) {
if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG,
/ "resumeTopActivityLocked: Skip resume: some activity pausing.");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return false;
}
? 如果我們的app里面正在暫停某個(gè)activity,那么我們什么都不要做等這個(gè)做完,因?yàn)闀和ctivity的過(guò)程是串行的,必須要一個(gè)一個(gè)按順序的來(lái)。不能同時(shí)來(lái),我認(rèn)為原因就是因?yàn)榭蛻?hù)端調(diào)用遠(yuǎn)程服務(wù)的過(guò)程的時(shí)候本地的客戶(hù)端所在線程會(huì)被掛起
/ We need to start pausing the current activity so the top one
// can be resumed...
//先把現(xiàn)在的當(dāng)前還是resumed的activity pause了,這樣新加進(jìn)來(lái)的activity才能resume?;A(chǔ)知識(shí)
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
//開(kāi)始暫定現(xiàn)在stack里面所有的activity
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
if (mResumedActivity != null) {
//開(kāi)始pausing當(dāng)前的所有activity,并且返回一個(gè)是否暫定成功的結(jié)果回來(lái)
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
}
? 這里就是在做把當(dāng)前啟動(dòng)者activity給pause掉,即至于為什么要這么做。。不用我多說(shuō)了吧。
? startPausingLocked(userLeaving, false, true, dontWaitForPause);這個(gè)函數(shù)跟著看下去就是通過(guò)AMS來(lái)暫停activity的過(guò)程。這個(gè)就不多說(shuō)了,大同小異。
最終在函數(shù)的末尾會(huì)又調(diào)用ActivityStackSupervisor的startSpecificActivityLocked(next, true, true);方法。這個(gè)方法的源碼如下:
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
//注意了,這里的app之后會(huì)用到,因?yàn)閍pp.thread就是獲得了applicationthread實(shí)例!
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);
}
//將app,信息完整的要啟動(dòng)的ActivityRecord類(lèi)的實(shí)例傳到另一個(gè)方法里面去
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);
}
繼續(xù)跟進(jìn)這個(gè)realStartActivityLocked()(真正啟動(dòng)activity的過(guò)程在這里):
final boolean realStartActivityLocked(ActivityRecord r,
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
r.startFreezingScreenLocked(app, 0);
if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
mWindowManager.setAppVisibility(r.appToken, true);
// schedule launch ticks to collect information about slow apps.
r.startLaunchTickingLocked();
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order. Note that
// as a result of this, it can call back into the activity
// manager with a new orientation. We don't care about that,
// because the activity is not currently running so we are
// just restarting it anyway.
if (checkConfig) {
Configuration config = mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
mService.updateConfigurationLocked(config, r, false, false);
}
r.app = app;
app.waitingToKill = null;
r.launchCount++;
r.lastLaunchTime = SystemClock.uptimeMillis();
if (localLOGV) Slog.v(TAG, "Launching: " + r);
int idx = app.activities.indexOf(r);
if (idx < 0) {
app.activities.add(r);
}
mService.updateLruProcessLocked(app, true, null);
mService.updateOomAdjLocked();
final ActivityStack stack = r.task.stack;
try {
if (app.thread == null) {
throw new RemoteException();
}
List<ResultInfo> results = null;
List<Intent> newIntents = null;
if (andResume) {
results = r.results;
newIntents = r.newIntents;
}
...省略代碼
//通過(guò)applicaitonthread調(diào)用客戶(hù)端binder實(shí)體的方法。
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
results, newIntents, !andResume, mService.isNextTransitionForward(),
profilerInfo);
...省略代碼
return true;
}
? 這里面兩個(gè)很重要的參數(shù),一個(gè)是ActivityRecord,一個(gè)是app。前者就是在ActivityStack里面轉(zhuǎn)了一圈之后得出來(lái)的最終要啟動(dòng)的Activity的信息記錄類(lèi)。后者就是用來(lái)獲得ApplicationThread來(lái)通知客戶(hù)端拿這個(gè)ActivityRecord去管理你的activity的生命周期吧!相當(dāng)于AMS給了ActivityThread一個(gè)任務(wù),讓后者去執(zhí)行。同樣,這也是一個(gè)IPC的過(guò)程。最終調(diào)用鏈繞了好大一圈終于又回到了ApplicaitonThread。
? 值得一提的是,凡是schedule開(kāi)頭的函數(shù)都是通過(guò)handler來(lái)做線程調(diào)度的,不服來(lái)辯。我們點(diǎn)進(jìn)去
public final void scheduleResumeActivity(IBinder token, int processState,
boolean isForward, Bundle resumeArgs) {
updateProcessState(processState, false);
sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
}
? 果然用handler發(fā)送了一個(gè)message。我們來(lái)看handler的處理會(huì)最終調(diào)用handlerLaunchActivity方法:
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);
? 可以看到activity的實(shí)例是由performLaunchActivity方法生成的。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
//獲得一些基本信息
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);
}
//通過(guò)Instrumentation利用類(lèi)加載器來(lái)生成一個(gè)activity實(shí)例
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);
}
}
//嘗試生成application
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
//創(chuàng)建contextImpl對(duì)象,并且調(diào)用activity的attach()方法來(lái)進(jìn)行一些activity初始化
if (activity != null) {
Context appContext = createBaseContextForActivity(r, activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
//設(shè)置activity的theme
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
mActivities.put(r.token, r);
return activity;
}
? 做了這些事情
- 從ActivityClientRecord中獲取獲取組件信息
- 通過(guò)Instrumentation創(chuàng)建Activity對(duì)象
- 通過(guò)LoadApk的makeApplication創(chuàng)建application,這個(gè)方法有興趣自己去看,就是一個(gè)單例而已。
- 創(chuàng)建contextImpl對(duì)象,并且調(diào)用activity的attach()方法來(lái)進(jìn)行一些activity初始化
- 調(diào)用activity的onCreat()方法
完成整個(gè)過(guò)程調(diào)用 ?。。?!
結(jié)束語(yǔ)
? 系統(tǒng)源碼看起來(lái)確實(shí)感覺(jué)自己置身茫茫大海一樣,特別是要去找一些不理解的問(wèn)題的時(shí)候。比如到底是被啟動(dòng)的activity的ActivityRecord實(shí)例先添加進(jìn)去還是在實(shí)例創(chuàng)建了之后才添加進(jìn)去,這個(gè)問(wèn)題我看源碼著了一天才還沒(méi)有什么結(jié)果,后來(lái)在別人的幫助和查閱老羅的資料才找到問(wèn)題所在。挺不錯(cuò)的一次過(guò)程,確實(shí)細(xì)節(jié)不必死扣,但是有些基本問(wèn)題不懂的話還是應(yīng)該去探究一下。
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。