Android中 Activity的啟動(dòng)過(guò)程有哪些,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供周口網(wǎng)站建設(shè)、周口做網(wǎng)站、周口網(wǎng)站設(shè)計(jì)、周口網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、周口企業(yè)網(wǎng)站模板建站服務(wù),十年周口做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
分析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= 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, ListpendingResults, List 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)。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。