這篇文章主要介紹“Android中Activity的啟動(dòng)過程是什么”的相關(guān)知識(shí),小編通過實(shí)際案例向大家展示操作過程,操作方法簡(jiǎn)單快捷,實(shí)用性強(qiáng),希望這篇“Android中Activity的啟動(dòng)過程是什么”文章能幫助大家解決問題。

成都創(chuàng)新互聯(lián)公司專注于鹽湖網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供鹽湖營(yíng)銷型網(wǎng)站建設(shè),鹽湖網(wǎng)站制作、鹽湖網(wǎng)頁設(shè)計(jì)、鹽湖網(wǎng)站官網(wǎng)定制、微信平臺(tái)小程序開發(fā)服務(wù),打造鹽湖網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供鹽湖網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。
分析Android Activity的啟動(dòng)過程
Activity作為Android的四大組件之一,也是最基本的組件,負(fù)責(zé)與用戶交互的所有功能。Activity的啟動(dòng)過程也并非一件神秘的事情,接下來就簡(jiǎn)單的從源碼的角度分析一下Activity的啟動(dòng)過程。
根Activity一般就是指我們項(xiàng)目中的MainActivity,代表了一個(gè)android應(yīng)用程序,一般也是在一個(gè)新的進(jìn)程中啟動(dòng)起來。在Android系統(tǒng)中,所有的Activity組件都保存在堆棧中,我們啟動(dòng)一個(gè)新的Activity組件就位于上一個(gè)Activity的上面。那么我們從桌面(Launcher)打開一個(gè)App是一個(gè)怎樣的過程呢,如下所示:
(1)Launcher向ActivityManagerService發(fā)送一個(gè)啟動(dòng)MainActivity的請(qǐng)求;
(2)ActivityManagerService首先將MainActivity的相關(guān)信息保存下來,然后向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)步保存下來的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ù),并且通過他來安裝系統(tǒng)中的應(yīng)用程序,在這個(gè)過程中,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é)果傳回來。
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來啟動(dòng)Activity,mInstrumentation類型為Instrumentation,用于監(jiān)控程序和系統(tǒng)之間的交互操作。mInstrumentation代為執(zhí)行Activity的啟動(dòng)操作,便于他可以監(jiān)控這一個(gè)交互過程。
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); //這里才是真正打開activity的地方,其核心功能在whoThread中完成。
checkStartActivityResult(result, intent); // 處理各種異常,如ActivityNotFound
} catch (RemoteException e) {
}
return null;
}上述代碼可知,通過ActivityManagerNative.getDefault()獲取一個(gè)ActivityManagerService的代理對(duì)象,然后調(diào)用他的startActivity方法來通知ActivityManagerService去啟動(dòng)Activity。
中間還有一系列過程,跟著源碼走下去,不難發(fā)現(xiàn),最后,是調(diào)用ApplicationThread的scheduleLaunchActivity來進(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ì)象來描述,他們保存在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)用來獲取一個(gè)LoaderApk對(duì)象并保存在ActivityClientRecord對(duì)象的成員變量packageInfo中。Loader對(duì)象用于描述一個(gè)已經(jīng)加載的APK文件。最后調(diào)用handleLaunchActivity來啟動(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(用戶界面可見)
!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) {
}
}
}到了這一步,那就很清晰了。憋了一口氣到這里,是不是突然放松了一下~~ 再來看看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)過程就結(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對(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ì)象一樣,都是用來描述所啟動(dòng)的Activity組件,只不過前者是在ActivityManagerService中使用,后者是在應(yīng)用程序進(jìn)程中使用。
至此,Activity的啟動(dòng)過程就分析完了。MainActivity的啟動(dòng)過程,其實(shí)也可以認(rèn)為是應(yīng)用程序的啟動(dòng)過程。
子Activity的啟動(dòng)過程和根Activity的啟動(dòng)過程也是類似的,過程如下:
(1)MainActivity向ActivityManagerService發(fā)送一個(gè)自動(dòng)ChildActivity的請(qǐng)求;
(2)ActivityManagerService首先將ChildActivity的信息保存下來,再向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)。
關(guān)于“Android中Activity的啟動(dòng)過程是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,小編每天都會(huì)為大家更新不同的知識(shí)點(diǎn)。
當(dāng)前名稱:Android中Activity的啟動(dòng)過程是什么
URL地址:http://chinadenli.net/article32/goehsc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、商城網(wǎng)站、服務(wù)器托管、網(wǎng)站排名、軟件開發(fā)、電子商務(wù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)