這篇文章主要介紹“Android中Activity的啟動過程是什么”的相關(guān)知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Android中Activity的啟動過程是什么”文章能幫助大家解決問題。
成都創(chuàng)新互聯(lián)公司專注于鹽湖網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供鹽湖營銷型網(wǎng)站建設(shè),鹽湖網(wǎng)站制作、鹽湖網(wǎng)頁設(shè)計、鹽湖網(wǎng)站官網(wǎng)定制、微信平臺小程序開發(fā)服務(wù),打造鹽湖網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供鹽湖網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
分析Android Activity的啟動過程
Activity作為Android的四大組件之一,也是最基本的組件,負(fù)責(zé)與用戶交互的所有功能。Activity的啟動過程也并非一件神秘的事情,接下來就簡單的從源碼的角度分析一下Activity的啟動過程。
根Activity一般就是指我們項目中的MainActivity,代表了一個android應(yīng)用程序,一般也是在一個新的進程中啟動起來。在Android系統(tǒng)中,所有的Activity組件都保存在堆棧中,我們啟動一個新的Activity組件就位于上一個Activity的上面。那么我們從桌面(Launcher)打開一個App是一個怎樣的過程呢,如下所示:
(1)Launcher向ActivityManagerService發(fā)送一個啟動MainActivity的請求;
(2)ActivityManagerService首先將MainActivity的相關(guān)信息保存下來,然后向Launcher發(fā)送一個使之進入中止?fàn)顟B(tài)的請求;
(3)Launcher收到中止?fàn)顟B(tài)之后,就會想ActivityManagerService發(fā)送一個已進入中止?fàn)顟B(tài)的請求,便于ActivityManagerService繼續(xù)執(zhí)行啟動MainActivity的操作;
(4)ActivityManagerService檢查用于運行MainActivity的進程,如果不存在,則啟動一個新的進程;
(5)新的應(yīng)用程序進程啟動完成之后,就會向ActivityManagerService發(fā)送一個啟動完成的請求,便于ActivityManagerService繼續(xù)執(zhí)行啟動MainActivity的操作;
(6)ActivityManagerService將第(2)步保存下來的MainActivity相關(guān)信息發(fā)送給新創(chuà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)我們在Launcher上點擊應(yīng)用程序圖標(biāo)時,startActivitySafely方法會被調(diào)用。需要啟動的Activity信息保存在intent中,包括action、category等等。那么Launcher是如何獲得intent里面的這些信息呢?首先,系統(tǒng)在啟動時會啟動一個叫做PackageManagerService的管理服務(wù),并且通過他來安裝系統(tǒng)中的應(yīng)用程序,在這個過程中,PackageManagerService會對應(yīng)用程序的配置文件AndroidManifest.xml進行解析,從而得到程序里的組件信息(包括Activity、Service、Broadcast等),然后PackageManagerService去查詢所有action為“android.intent.action.MAIN”并且category為“android.intent.category.LAUNCHER”的Activity,然后為每個應(yīng)用程序創(chuàng)建一個快捷方式圖標(biāo),并把程序信息與之關(guān)聯(lián)。上述代碼中,Activity的啟動標(biāo)志位設(shè)置為“Intent.FLAG_ACTIVITY_NEW_TASK”,便于他可以在一個新的任務(wù)中啟動。
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,第二個參數(shù)(requestCode)為-1則表示在Activity關(guān)閉時不需要將結(jié)果傳回來。
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會被調(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),最后實際上是調(diào)用mInstrumentation.execStartActivity來啟動Activity,mInstrumentation類型為Instrumentation,用于監(jiān)控程序和系統(tǒng)之間的交互操作。mInstrumentation代為執(zhí)行Activity的啟動操作,便于他可以監(jiān)控這一個交互過程。
mMainThread的類型為ActivityThread,用于描述一個應(yīng)用程序進程,系統(tǒng)每啟動一個程序都會在它里面加載一個ActivityThread的實例,并且將該實例保存在Activity的成員變量mMainThread中,而mMainThread.getApplicationThread()則用于獲取其內(nèi)部一個類型為ApplicationThread的本地Binder對象。mToken的類型為IBinder,他是一個Binder的代理對象,只想了ActivityManagerService中一個類型為ActivityRecord的本地Binder對象。每一個已經(jīng)啟動的Activity在ActivityManagerService中都有一個對應(yīng)的ActivityRecord對象,用于維護Activity的運行狀態(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); //這里才是真正打開activity的地方,其核心功能在whoThread中完成。 checkStartActivityResult(result, intent); // 處理各種異常,如ActivityNotFound } catch (RemoteException e) { } return null; }
上述代碼可知,通過ActivityManagerNative.getDefault()獲取一個ActivityManagerService的代理對象,然后調(diào)用他的startActivity方法來通知ActivityManagerService去啟動Activity。
中間還有一系列過程,跟著源碼走下去,不難發(fā)現(xiàn),最后,是調(diào)用ApplicationThread的scheduleLaunchActivity來進行Activity的啟動。
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)造一個ActivityClientRecord,然后調(diào)用sendMessage發(fā)送一個消息。在應(yīng)用程序?qū)?yīng)的進程中,每一個Activity組件都使用一個ActivityClientRecord對象來描述,他們保存在ActivityThread類的成員變量mActivities中。那么Handler是如何處理這個消息的呢?
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)成一個ActivityClientRecord對象,然后調(diào)用來獲取一個LoaderApk對象并保存在ActivityClientRecord對象的成員變量packageInfo中。Loader對象用于描述一個已經(jīng)加載的APK文件。最后調(diào)用handleLaunchActivity來啟動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被實例化,onCreate被調(diào)用 if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; handleResumeActivity(r.token, false, r.isForward, // 再調(diào)用Activity實例的Resume(用戶界面可見) !r.activity.mFinished && !r.startsNotResumed); if (!r.activity.mFinished && r.startsNotResumed) { try { r.activity.mCalled = false; mInstrumentation.callActivityOnPause(r.activity); // finish的時候先調(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) { } } }
到了這一步,那就很清晰了。憋了一口氣到這里,是不是突然放松了一下~~ 再來看看performLaunchActivity做的事兒~~performLaunchActivity函數(shù)加載用戶自定義的Activity的派生類,并執(zhí)行其onCreate函數(shù),它將返回此Activity對象。
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的啟動參數(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實例 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對象,作為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啟動過程就結(jié)束了,其生命周期由ApplicationThread來管理 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對象保存在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,是一個Binder的代理對象,和ActivityClientRecord對象一樣,都是用來描述所啟動的Activity組件,只不過前者是在ActivityManagerService中使用,后者是在應(yīng)用程序進程中使用。
至此,Activity的啟動過程就分析完了。MainActivity的啟動過程,其實也可以認(rèn)為是應(yīng)用程序的啟動過程。
子Activity的啟動過程和根Activity的啟動過程也是類似的,過程如下:
(1)MainActivity向ActivityManagerService發(fā)送一個自動ChildActivity的請求;
(2)ActivityManagerService首先將ChildActivity的信息保存下來,再向MainActivity發(fā)送一個中止的請求;
(3)MainActivity收到請求進入中止?fàn)顟B(tài),告訴ActivityManagerService,便于ActivityManagerService繼續(xù)執(zhí)行啟動ChildActivity的操作
(4)ActivityManagerService檢查ChildActivity所運行的進程是否存在,存在就發(fā)送ChildActivity信息給他,以進行啟動。
關(guān)于“Android中Activity的啟動過程是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點。