溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android中 Activity的啟動(dòng)過程有哪些

發(fā)布時(shí)間:2021-06-29 14:45:58 來源:億速云 閱讀:84 作者:Leah 欄目:移動(dòng)開發(fā)

Android中 Activity的啟動(dòng)過程有哪些,很多新手對此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

分析Android Activity的啟動(dòng)過程

          對于Android Activity 的啟動(dòng)過程,我在Android源碼中讀了好久的源碼,以下是我整理出來的Activity啟動(dòng)過程和大家分享下:

Activity作為Android的四大組件之一,也是最基本的組件,負(fù)責(zé)與用戶交互的所有功能。Activity的啟動(dòng)過程也并非一件神秘的事情,接下來就簡單的從源碼的角度分析一下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的請求;
    (2)ActivityManagerService首先將MainActivity的相關(guān)信息保存下來,然后向Launcher發(fā)送一個(gè)使之進(jìn)入中止?fàn)顟B(tài)的請求;
    (3)Launcher收到中止?fàn)顟B(tài)之后,就會(huì)想ActivityManagerService發(fā)送一個(gè)已進(jìn)入中止?fàn)顟B(tài)的請求,便于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)完成的請求,便于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)我們在Launcher上點(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ì)對應(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對象。mToken的類型為IBinder,他是一個(gè)Binder的代理對象,只想了ActivityManagerService中一個(gè)類型為ActivityRecord的本地Binder對象。每一個(gè)已經(jīng)啟動(dòng)的Activity在ActivityManagerService中都有一個(gè)對應(yīng)的ActivityRecord對象,用于維護(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的代理對象,然后調(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對象來描述,他們保存在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對象,然后調(diào)用來獲取一個(gè)LoaderApk對象并保存在ActivityClientRecord對象的成員變量packageInfo中。Loader對象用于描述一個(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對象。

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對象,作為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對象保存在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的代理對象,和ActivityClientRecord對象一樣,都是用來描述所啟動(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的請求;

    (2)ActivityManagerService首先將ChildActivity的信息保存下來,再向MainActivity發(fā)送一個(gè)中止的請求;

    (3)MainActivity收到請求進(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)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI