分析Android Activity的啟動(dòng)過(guò)程
分析Android Activity的啟動(dòng)過(guò)程
對(duì)于Android Activity 的啟動(dòng)過(guò)程,我在Android源碼中讀了好久的源碼,以下是我整理出來(lái)的Activity啟動(dòng)過(guò)程和大家分享下:
Activity作為Android的四大組件之一,也是最基本的組件,負(fù)責(zé)與用戶交互的所有功能。Activity的啟動(dòng)過(guò)程也并非一件神秘的事情,接下來(lái)就簡(jiǎn)單的從源碼的角度分析一下Activity的啟動(dòng)過(guò)程。
根Activity一般就是指我們項(xiàng)目中的MainActivity,代表了一個(gè)android應(yīng)用程序,一般也是在一個(gè)新的進(jìn)程中啟動(dòng)起來(lái)。在Android系統(tǒng)中,所有的Activity組件都保存在堆棧中,我們啟動(dòng)一個(gè)新的Activity組件就位于上一個(gè)Activity的上面。那么我們從桌面(Launcher)打開(kāi)一個(gè)App是一個(gè)怎樣的過(guò)程呢,如下所示:
(1)Launcher向ActivityManagerService發(fā)送一個(gè)啟動(dòng)MainActivity的請(qǐng)求;
(2)ActivityManagerService首先將MainActivity的相關(guān)信息保存下來(lái),然后向Launcher發(fā)送一個(gè)使之進(jìn)入中止?fàn)顟B(tài)的請(qǐng)求;
(3)Launcher收到中止?fàn)顟B(tài)之后,就會(huì)想ActivityManagerService發(fā)送一個(gè)已進(jìn)入中止?fàn)顟B(tài)的請(qǐng)求,便于ActivityManagerService繼續(xù)執(zhí)行啟動(dòng)MainActivity的操作;
(4)ActivityManagerService檢查用于運(yùn)行MainActivity的進(jìn)程,如果不存在,則啟動(dòng)一個(gè)新的進(jìn)程;
(5)新的應(yīng)用程序進(jìn)程啟動(dòng)完成之后,就會(huì)向ActivityManagerService發(fā)送一個(gè)啟動(dòng)完成的請(qǐng)求,便于ActivityManagerService繼續(xù)執(zhí)行啟動(dòng)MainActivity的操作;
(6)ActivityManagerService將第(2)步保存下來(lái)的MainActivity相關(guān)信息發(fā)送給新創(chuàng)建的進(jìn)程,便于該進(jìn)程啟動(dòng)MainActivity組件。
Launcher.startActivitySafely
boolean startActivitySafely(Intent intent, Object tag) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); try { startActivity(intent); return true; } catch (ActivityNotFoundException e) {} }
當(dāng)我們?cè)贚auncher上點(diǎn)擊應(yīng)用程序圖標(biāo)時(shí),startActivitySafely方法會(huì)被調(diào)用。需要啟動(dòng)的Activity信息保存在intent中,包括action、category等等。那么Launcher是如何獲得intent里面的這些信息呢?首先,系統(tǒng)在啟動(dòng)時(shí)會(huì)啟動(dòng)一個(gè)叫做PackageManagerService的管理服務(wù),并且通過(guò)他來(lái)安裝系統(tǒng)中的應(yīng)用程序,在這個(gè)過(guò)程中,PackageManagerService會(huì)對(duì)應(yīng)用程序的配置文件AndroidManifest.xml進(jìn)行解析,從而得到程序里的組件信息(包括Activity、Service、Broadcast等),然后PackageManagerService去查詢所有action為“android.intent.action.MAIN”并且category為“android.intent.category.LAUNCHER”的Activity,然后為每個(gè)應(yīng)用程序創(chuàng)建一個(gè)快捷方式圖標(biāo),并把程序信息與之關(guān)聯(lián)。上述代碼中,Activity的啟動(dòng)標(biāo)志位設(shè)置為“Intent.FLAG_ACTIVITY_NEW_TASK”,便于他可以在一個(gè)新的任務(wù)中啟動(dòng)。
Activity.startActivity
@Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { startActivityForResult(intent, -1); } }
調(diào)用startActivityForResult,第二個(gè)參數(shù)(requestCode)為-1則表示在Activity關(guān)閉時(shí)不需要將結(jié)果傳回來(lái)。
Activity.startActivityForResult
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { //一般的Activity其mParent都為null Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options); if (ar != null) { //發(fā)送結(jié)果,即onActivityResult會(huì)被調(diào)用 mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } if (requestCode >= 0) { mStartedActivity = true; } final View decor = mWindow != null ? mWindow.peekDecorView() : null; if (decor != null) { decor.cancelPendingInputEvents(); } } else { //在ActivityGroup內(nèi)部的Activity,內(nèi)部處理邏輯和上面是類似的 if (options != null) { mParent.startActivityFromChild(this, intent, requestCode, options); } else { mParent.startActivityFromChild(this, intent, requestCode); } } if (options != null && !isTopOfTask()) { mActivityTransitionState.startExitOutTransition(this, options); } }
不難發(fā)現(xiàn),最后實(shí)際上是調(diào)用mInstrumentation.execStartActivity來(lái)啟動(dòng)Activity,mInstrumentation類型為Instrumentation,用于監(jiān)控程序和系統(tǒng)之間的交互操作。mInstrumentation代為執(zhí)行Activity的啟動(dòng)操作,便于他可以監(jiān)控這一個(gè)交互過(guò)程。
mMainThread的類型為ActivityThread,用于描述一個(gè)應(yīng)用程序進(jìn)程,系統(tǒng)每啟動(dòng)一個(gè)程序都會(huì)在它里面加載一個(gè)ActivityThread的實(shí)例,并且將該實(shí)例保存在Activity的成員變量mMainThread中,而mMainThread.getApplicationThread()則用于獲取其內(nèi)部一個(gè)類型為ApplicationThread的本地Binder對(duì)象。mToken的類型為IBinder,他是一個(gè)Binder的代理對(duì)象,只想了ActivityManagerService中一個(gè)類型為ActivityRecord的本地Binder對(duì)象。每一個(gè)已經(jīng)啟動(dòng)的Activity在ActivityManagerService中都有一個(gè)對(duì)應(yīng)的ActivityRecord對(duì)象,用于維護(hù)Activity的運(yùn)行狀態(tài)及信息。
Instrumentation.execStartActivity
public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { //先查找一遍看是否存在這個(gè)activity final ActivityMonitor am = mActivityMonitors.get(i); if (am.match(who, null, intent)) { am.mHits++; if (am.isBlocking()) { return requestCode >= 0 ? am.getResult() : null; } break; } } } } 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); //這里才是真正打開(kāi)activity的地方,其核心功能在whoThread中完成。 checkStartActivityResult(result, intent); // 處理各種異常,如ActivityNotFound } catch (RemoteException e) { } return null; }
上述代碼可知,通過(guò)ActivityManagerNative.getDefault()獲取一個(gè)ActivityManagerService的代理對(duì)象,然后調(diào)用他的startActivity方法來(lái)通知ActivityManagerService去啟動(dòng)Activity。
中間還有一系列過(guò)程,跟著源碼走下去,不難發(fā)現(xiàn),最后,是調(diào)用ApplicationThread的scheduleLaunchActivity來(lái)進(jìn)行Activity的啟動(dòng)。
Application.scheduleLaunchActivity
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, ActivityInfo info, Configuration curConfig, 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; updatePendingConfiguration(curConfig); sendMessage(H.LAUNCH_ACTIVITY, r); }
上述代碼主要做的事就是構(gòu)造一個(gè)ActivityClientRecord,然后調(diào)用sendMessage發(fā)送一個(gè)消息。在應(yīng)用程序?qū)?yīng)的進(jìn)程中,每一個(gè)Activity組件都使用一個(gè)ActivityClientRecord對(duì)象來(lái)描述,他們保存在ActivityThread類的成員變量mActivities中。那么Handler是如何處理這個(gè)消息的呢?
H.handleMessage
switch (msg.what) { // 消息類型 case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null); // 處理消息 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord)msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2, (msg.arg1&2) != 0); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; ... ... }
首先將msg里面的obj轉(zhuǎn)成一個(gè)ActivityClientRecord對(duì)象,然后調(diào)用來(lái)獲取一個(gè)LoaderApk對(duì)象并保存在ActivityClientRecord對(duì)象的成員變量packageInfo中。Loader對(duì)象用于描述一個(gè)已經(jīng)加載的APK文件。最后調(diào)用handleLaunchActivity來(lái)啟動(dòng)Activity組件。
ActivityThread.handleLaunchActivity
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { unscheduleGcIdler(); mSomeActivitiesChanged = true; if (r.profilerInfo != null) { mProfiler.setProfiler(r.profilerInfo); mProfiler.startProfiling(); } handleConfigurationChanged(null, null); if (localLOGV) Slog.v( TAG, "Handling launch of " + r); WindowManagerGlobal.initialize(); Activity a = performLaunchActivity(r, customIntent); //performLaunchActivity真正完成了activity的調(diào)起,Activity被實(shí)例化,onCreate被調(diào)用 if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; handleResumeActivity(r.token, false, r.isForward, // 再調(diào)用Activity實(shí)例的Resume(用戶界面可見(jiàn)) !r.activity.mFinished && !r.startsNotResumed); if (!r.activity.mFinished && r.startsNotResumed) { try { r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity); // finish的時(shí)候先調(diào)onPause if (r.isPreHoneycomb()) { r.state = oldState; } if (!r.activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " 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 " + r.intent.getComponent().toShortString() + ": " + e.toString(), e); } } r.paused = true; } } else { try { ActivityManagerNative.getDefault() // finishActivity 一樣的原理 .finishActivity(r.token, Activity.RESULT_CANCELED, null, false); } catch (RemoteException ex) { } } }
到了這一步,那就很清晰了。憋了一口氣到這里,是不是突然放松了一下~~ 再來(lái)看看performLaunchActivity做的事兒~~performLaunchActivity函數(shù)加載用戶自定義的Activity的派生類,并執(zhí)行其onCreate函數(shù),它將返回此Activity對(duì)象。
ActivityThread.performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); } //從intent中取出目標(biāo)activity的啟動(dòng)參數(shù)(包名、類名等) 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); } Activity activity = null; try { java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); // 將Activity類文件加載到內(nèi)存中 activity = mInstrumentation.newActivity( // 創(chuàng)建Activity實(shí)例 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); } } try { Application app = r.packageInfo.makeApplication(false, mInstrumentation); if (localLOGV) Slog.v(TAG, "Performing launch of " + r); if (localLOGV) Slog.v( TAG, r + ": app=" + app + ", appName=" + app.getPackageName() + ", pkg=" + r.packageInfo.getPackageName() + ", comp=" + r.intent.getComponent().toShortString() + ", dir=" + r.packageInfo.getAppDir()); if (activity != null) { Context appContext = createBaseContextForActivity(r, activity); // 初始化Context對(duì)象,作為Activity的上下文 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); Configuration config = new Configuration(mCompatConfiguration); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " + r.activityInfo.name + " with config " + config); 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); if (customIntent != null) { activity.mIntent = customIntent; } r.lastNonConfigurationInstances = null; activity.mStartedActivity = false; int theme = r.activityInfo.getThemeResource(); if (theme != 0) { activity.setTheme(theme); } activity.mCalled = false; if (r.isPersistable()) { //下面就是調(diào)用到acitivity的onCreate方法了 mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); } // 至此,Activity啟動(dòng)過(guò)程就結(jié)束了,其生命周期由ApplicationThread來(lái)管理 if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()"); } r.activity = activity; r.stopped = true; if (!r.activity.mFinished) { activity.performStart(); r.stopped = false; } if (!r.activity.mFinished) { if (r.isPersistable()) { if (r.state != null || r.persistentState != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state, r.persistentState); } } else if (r.state != null) { mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); } } if (!r.activity.mFinished) { activity.mCalled = false; if (r.isPersistable()) { mInstrumentation.callActivityOnPostCreate(activity, r.state, r.persistentState); } else { mInstrumentation.callActivityOnPostCreate(activity, r.state); } if (!activity.mCalled) { throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()"); } } } r.paused = true; mActivities.put(r.token, r); // 將ActivityRecord對(duì)象保存在ActivityThread的mActivities中 } catch (SuperNotCalledException e) { throw e; } catch (Exception e) { if (!mInstrumentation.onException(activity, e)) { throw new RuntimeException( "Unable to start activity " + component + ": " + e.toString(), e); } } return activity; }
ActivityRecord里面的token,是一個(gè)Binder的代理對(duì)象,和ActivityClientRecord對(duì)象一樣,都是用來(lái)描述所啟動(dòng)的Activity組件,只不過(guò)前者是在ActivityManagerService中使用,后者是在應(yīng)用程序進(jìn)程中使用。
至此,Activity的啟動(dòng)過(guò)程就分析完了。MainActivity的啟動(dòng)過(guò)程,其實(shí)也可以認(rèn)為是應(yīng)用程序的啟動(dòng)過(guò)程。
子Activity的啟動(dòng)過(guò)程和根Activity的啟動(dòng)過(guò)程也是類似的,過(guò)程如下:
(1)MainActivity向ActivityManagerService發(fā)送一個(gè)自動(dòng)ChildActivity的請(qǐng)求;
(2)ActivityManagerService首先將ChildActivity的信息保存下來(lái),再向MainActivity發(fā)送一個(gè)中止的請(qǐng)求;
(3)MainActivity收到請(qǐng)求進(jìn)入中止?fàn)顟B(tài),告訴ActivityManagerService,便于ActivityManagerService繼續(xù)執(zhí)行啟動(dòng)ChildActivity的操作
(4)ActivityManagerService檢查ChildActivity所運(yùn)行的進(jìn)程是否存在,存在就發(fā)送ChildActivity信息給他,以進(jìn)行啟動(dòng)。
源代碼方面,原理類似,相比起來(lái)會(huì)比MainActivity的稍微簡(jiǎn)單一些,這里就不再詳細(xì)敘述了,各位可以自行根據(jù)前面步驟,閱讀源代碼。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
RecyclerView實(shí)現(xiàn)側(cè)滑拖拽功能
這篇文章主要為大家詳細(xì)介紹了RecyclerView實(shí)現(xiàn)側(cè)滑拖拽功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07Android?Choreographer源碼詳細(xì)分析
Choreographer的作用主要是配合Vsync,給上層App的渲染提供一個(gè)穩(wěn)定的Message處理的時(shí)機(jī),也就是Vsync到來(lái)的時(shí)候,系統(tǒng)通過(guò)對(duì)Vsync信號(hào)周期的調(diào)整,來(lái)控制每一幀繪制操作的時(shí)機(jī)2022-08-08Android開(kāi)發(fā)之TextView使用intent傳遞信息,實(shí)現(xiàn)注冊(cè)界面功能示例
這篇文章主要介紹了Android開(kāi)發(fā)之TextView使用intent傳遞信息,實(shí)現(xiàn)注冊(cè)界面功能,涉及Android使用intent傳值及界面布局等相關(guān)操作技巧,需要的朋友可以參考下2019-04-04Android 5.0最應(yīng)該實(shí)現(xiàn)的8個(gè)期望
毫無(wú)疑問(wèn),Android 5 將是令人興奮的操作系統(tǒng),因?yàn)?Android4.0 至 4.4 版本之間并沒(méi)有顯著的差異,顯然谷歌會(huì)在 5.0 版本中進(jìn)行一些較大幅度的革新2016-01-01Android使用View Animation實(shí)現(xiàn)動(dòng)畫(huà)加載界面
這篇文章主要為大家詳細(xì)介紹了Android使用View Animation實(shí)現(xiàn)動(dòng)畫(huà)加載界面的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04Android消息機(jī)制Handler用法總結(jié)
這篇文章介紹了Android消息機(jī)制Handler用法總結(jié),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-11-11Android開(kāi)發(fā)實(shí)現(xiàn)切換主題及換膚功能示例
這篇文章主要介紹了Android開(kāi)發(fā)實(shí)現(xiàn)切換主題及換膚功能,涉及Android界面布局與樣式動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-03-03android Textview文字監(jiān)控(Textview使用方法)
以手機(jī)號(hào)充值為例,當(dāng)用戶輸入最后一位數(shù)時(shí)候,進(jìn)行匯率的變換,本文就實(shí)現(xiàn)類似這樣的功能2013-11-11