Android應(yīng)用程序啟動(dòng)流程

Activity啟動(dòng)流程

文章摘抄自:http://liuwangshu.cn/framework/component/1-activity-start-1.html

一.Launcher點(diǎn)擊桌面按鈕啟動(dòng)應(yīng)用

我們知道Android系統(tǒng)每個(gè)應(yīng)用都是一個(gè)單獨(dú)的進(jìn)程,所以我們?cè)邳c(diǎn)擊桌面圖標(biāo)時(shí)ActivityManagerService會(huì)檢查當(dāng)前應(yīng)用的進(jìn)程是否存在,如果不存在會(huì)就會(huì)請(qǐng)求Zygote進(jìn)程將需要的應(yīng)用程序進(jìn)程啟動(dòng)。在系統(tǒng)啟動(dòng)時(shí)在Zygote的Java框架層中,會(huì)創(chuàng)建一個(gè)Server端的Socket,這個(gè)Socket用來等待ActivityManagerService來請(qǐng)求Zygote來創(chuàng)建新的應(yīng)用程序進(jìn)程的。我們知道Zygote進(jìn)程通過fock自身創(chuàng)建的應(yīng)用程序進(jìn)程,這樣應(yīng)用程序程序進(jìn)程就會(huì)獲得Zygote進(jìn)程在啟動(dòng)時(shí)創(chuàng)建的虛擬機(jī)實(shí)例。當(dāng)然,在應(yīng)用程序創(chuàng)建過程中除了獲取虛擬機(jī)實(shí)例,還可以獲得Binder線程池和消息循環(huán),這樣運(yùn)行在應(yīng)用進(jìn)程中應(yīng)用程序就可以方便的使用Binder進(jìn)行進(jìn)程間通信以及消息處理機(jī)制了。
關(guān)于應(yīng)用程序的進(jìn)程啟動(dòng)在后面的文章進(jìn)行分析,今天講一下應(yīng)用程序啟動(dòng)的流程。

1.Launcher請(qǐng)求ActivityManagerService過程

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
點(diǎn)擊按鈕后會(huì)執(zhí)行按鈕的點(diǎn)擊事件,觸發(fā)startActivitySafely方法

 /**
     * Launches the intent referred by the clicked shortcut.
     *
     * @param v The view representing the clicked shortcut.
     */
    public void onClick(View v) {
     。。。。。省略。。。。。
        Object tag = v.getTag();
        if (tag instanceof ShortcutInfo) {
            // Open shortcut
            final Intent intent = ((ShortcutInfo) tag).intent;
            int[] pos = new int[2];
            v.getLocationOnScreen(pos);
            intent.setSourceBounds(new Rect(pos[0], pos[1],
                    pos[0] + v.getWidth(), pos[1] + v.getHeight()));

            boolean success = startActivitySafely(v, intent, tag);
      。。。。。省略。。。。。
         
    }
        
  boolean startActivitySafely(View v, Intent intent, Object tag) {
        boolean success = false;
        try {
            success = startActivity(v, intent, tag);
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + tag + " intent=" + intent, e);
        }
        return success;
    }

startActivitySafely函數(shù)中主要就是調(diào)用了startActivity函數(shù):
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

private boolean startActivity(View v, Intent intent, Object tag) {
     設(shè)置Flag為Intent.FLAG_ACTIVITY_NEW_TASK,這樣根Activity會(huì)在新的任務(wù)棧中啟動(dòng)。
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
       try {
         ...
           if (user == null || user.equals(UserHandleCompat.myUserHandle())) {
               StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
               try {            
                   StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll()
                           .penaltyLog().build());
                   startActivity(intent, optsBundle);
               } finally {
                   StrictMode.setVmPolicy(oldPolicy);
               }
           } else {
               launcherApps.startActivityForProfile(intent.getComponent(), user,
                       intent.getSourceBounds(), optsBundle);
           }
           return true;
       } catch (SecurityException e) {      
         ...
       }
       return false;
   }

**
startActivity(intent, optsBundle)處調(diào)用了startActivity函數(shù):
frameworks/base/core/java/android/app/Activity.java

Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

**
startActivity會(huì)調(diào)用startActivityForResult函數(shù),其中第二個(gè)參數(shù)為-1,表示Launcher不需要知道Activity啟動(dòng)的結(jié)果,startActivityForResult函數(shù)的代碼如下所示。

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
           @Nullable Bundle options) {
       if (mParent == null) {
           Instrumentation.ActivityResult ar =
               mInstrumentation.execStartActivity(
                   this, mMainThread.getApplicationThread(), mToken, this,
                   intent, requestCode, options);
        ...
       } else {
        ...
       }
   }

**mParent是Activity類型的,表示當(dāng)前Activity的父類。因?yàn)槟壳案鵄ctivity還沒有創(chuàng)建出來,因此,mParent == null成立。接著調(diào)用Instrumentation的execStartActivity方法,Instrumentation主要用來監(jiān)控應(yīng)用程序和系統(tǒng)的交互,execStartActivity方法的代碼如下所示。
frameworks/base/core/java/android/app/Instrumentation.java
**

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
      ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

**
調(diào)用ActivityManagerService的startActivity方法,這里是用ActivityManagerNative.getDefault()來獲取ActivityManagerService(以后簡(jiǎn)稱為AMS)的代理對(duì)象,我們來看一下是怎么獲取的。
frameworks/base/core/java/android/app/ActivityManagerNative.java

 static public IActivityManager getDefault() {
        return gDefault.get();
    }

    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };
}

**
getDefault()方法調(diào)用了gDefault的get()方法,gDefault是一個(gè)Singleton類,IBinder b = ServiceManager.getService("activity")獲取到“activity”的IBinder引用,就是IBinder類型的ActivityManagerService引用,然后用asInterface方法封裝成ActivityManagerProxy(以后簡(jiǎn)稱為AMP)類型對(duì)象,并將它保存到gDefault中,此后調(diào)用ActivityManagerNative的getDefault方法就會(huì)直接獲得AMS的代理AMP對(duì)象。回到Instrumentation類的execStartActivity方法中,從上面得知就是調(diào)用AMP的startActivity,其中AMP是ActivityManagerNative的內(nèi)部類,代碼如下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
           String resolvedType, IBinder resultTo, String resultWho, int requestCode,
           int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
       Parcel data = Parcel.obtain();
       Parcel reply = Parcel.obtain();
       data.writeInterfaceToken(IActivityManager.descriptor);
       data.writeStrongBinder(caller != null ? caller.asBinder() : null);
       data.writeString(callingPackage);
       intent.writeToParcel(data, 0);
       data.writeString(resolvedType);
       data.writeStrongBinder(resultTo);
       data.writeString(resultWho);
       data.writeInt(requestCode);
       data.writeInt(startFlags);
       if (profilerInfo != null) {
           data.writeInt(1);
           profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
       } else {
           data.writeInt(0);
       }
       if (options != null) {
           data.writeInt(1);
           options.writeToParcel(data, 0);
       } else {
           data.writeInt(0);
       }
       mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//1
       reply.readException();
       int result = reply.readInt();
       reply.recycle();
       data.recycle();
       return result;
   }

**
首先會(huì)將傳入的參數(shù)寫入到Parcel類型的data中。在注釋1處通過IBinder類型對(duì)象mRemote向AMS發(fā)送一個(gè)START_ACTIVITY_TRANSACTION類型的進(jìn)程間通信請(qǐng)求。那么服務(wù)端AMS就會(huì)從Binder線程池中讀取我們客戶端發(fā)來的數(shù)據(jù),最終會(huì)調(diào)用ActivityManagerNative的onTransact方法中執(zhí)行,如下所示。
frameworks/base/core/java/android/app/ActivityManagerNative.java

@Override
   public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
           throws RemoteException {
       switch (code) {
       case START_ACTIVITY_TRANSACTION:
       {
   ...
           int result = startActivity(app, callingPackage, intent, resolvedType,
                   resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
           reply.writeNoException();
           reply.writeInt(result);
           return true;
       }
   }

**
onTransact中會(huì)調(diào)用AMS的startActivity方法,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
 public final int startActivity(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
             resultWho, requestCode, startFlags, profilerInfo, bOptions,
             UserHandle.getCallingUserId());
 }

**
**

image.png
image.png

**

2.ActivityManageService到ApplicationThread的調(diào)用流程

**AMS的startActivity方法中return了startActivityAsUser方法:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override
 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
     enforceNotIsolatedCaller("startActivity");
     userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
             userId, false, ALLOW_FULL_ONLY, "startActivity", null);
     return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
             resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
             profilerInfo, null, null, bOptions, false, userId, null, null);

startActivityAsUser方法中又return了mActivityStarter的startActivityMayWait方法,代碼如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

final int startActivityMayWait(IApplicationThread caller, int callingUid,
         String callingPackage, Intent intent, String resolvedType,
         IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
         IBinder resultTo, String resultWho, int requestCode, int startFlags,
         ProfilerInfo profilerInfo, IActivityManager.WaitResult outResult, Configuration config,
         Bundle bOptions, boolean ignoreTargetSecurity, int userId,
         IActivityContainer iContainer, TaskRecord inTask) {
   ...
         int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                 aInfo, rInfo, voiceSession, voiceInteractor,
                 resultTo, resultWho, requestCode, callingPid,
                 callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                 options, ignoreTargetSecurity, componentSpecified, outRecord, container,
                 inTask);

     ...
         return res;
     }
 }

又調(diào)用了startActivityLocked方法,代碼如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
           String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
           IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
           IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
           String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
           ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
           ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
           TaskRecord inTask) {
      ...

       doPendingActivityLaunchesLocked(false);

      ...
       return err;
   }

startActivityLocked函數(shù)代碼非常多,我們只需要關(guān)注doPendingActivityLaunchesLocked方法,代碼如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

final void doPendingActivityLaunchesLocked(boolean doResume) {
       while (!mPendingActivityLaunches.isEmpty()) {
           final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
           final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
           try {
               final int result = startActivityUnchecked(
                       pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
               postStartActivityUncheckedProcessing(
                       pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord,
                       mTargetStack);
           } catch (Exception e) {
               Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
               pal.sendErrorResult(e.getMessage());
           }
       }
   }

接著又調(diào)用startActivityUnchecked方法:
frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
           IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
           int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
     ...  
        mSupervisor.resumeFocusedStackTopActivityLocked();  
     ... 
       return START_SUCCESS;
   }

startActivityUnchecked方法中調(diào)用了ActivityStackSupervisor類型的mSupervisor的resumeFocusedStackTopActivityLocked方法,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(
           ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
       if (targetStack != null && isFocusedStack(targetStack)) {
           return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
       }
       final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
       if (r == null || r.state != RESUMED) {
           mFocusedStack.resumeTopActivityUncheckedLocked(null, null);//1
       }
       return false;
   }

在注釋1處又調(diào)用了ActivityStack類型mFocusedStack的resumeTopActivityUncheckedLocked方法:
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

 boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
...
        try {
           ...
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

緊接著查看ActivityStack的resumeTopActivityInnerLocked方法:
frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
      ...
           mStackSupervisor.startSpecificActivityLocked(next, true, true);
       }
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
       return true;

resumeTopActivityInnerLocked方法代碼非常多,我們只需要關(guān)注調(diào)用了ActivityStackSupervisor類型mStackSupervisor的startSpecificActivityLocked方法,代碼如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

void startSpecificActivityLocked(ActivityRecord r,
          boolean andResume, boolean checkConfig) {
      ProcessRecord app = mService.getProcessRecordLocked(r.processName,
              r.info.applicationInfo.uid, true);
      r.task.stack.setLaunchTime(r);
      if (app != null && app.thread != null) {//1
          try {
              if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                      || !"android".equals(r.info.packageName)) {
                  app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                          mService.mProcessStats);
              }
              realStartActivityLocked(r, app, andResume, checkConfig);//2
              return;
          } catch (RemoteException e) {
              Slog.w(TAG, "Exception when starting activity "
                      + r.intent.getComponent().flattenToShortString(), e);
          }
      }
      mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
              "activity", r.intent.getComponent(), false, false, true);
  }

在注釋1處如果當(dāng)前Activity所在的Application運(yùn)行的話,會(huì)執(zhí)行注釋2處的代碼。realStartActivityLocked方法的代碼如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
          boolean andResume, boolean checkConfig) throws RemoteException {
   ...
          app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                  System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                  new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
                  task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                  newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);

  ...      

      return true;
  }

這里的 app.thread指的是IApplicationThread,它的實(shí)現(xiàn)是ActivityThread的內(nèi)部類ApplicationThread,其中ApplicationThread繼承了ApplicationThreadNative,而ApplicationThreadNative繼承了Binder并實(shí)現(xiàn)了IApplicationThread接口。

講到這里再給出ActivityManageService到ApplicationThread調(diào)用過程的時(shí)序圖,如下圖所示
image.png
image.png

3.ActivityThread啟動(dòng)Activity

**在應(yīng)用程序進(jìn)程啟動(dòng)時(shí)會(huì)創(chuàng)建ActivityThread實(shí)例。ActivityThread作為應(yīng)用程序進(jìn)程的核心類,它是如何啟動(dòng)應(yīng)用程序(Activity)的呢?我們接著往下看。
根據(jù)上文接著查看ApplicationThread的scheduleLaunchActivity方法,代碼如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
        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;
    r.overrideConfig = overrideConfig;
    updatePendingConfiguration(curConfig);
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

scheduleLaunchActivity方法會(huì)將啟動(dòng)Activity的參數(shù)封裝成ActivityClientRecord ,sendMessage方法向H類發(fā)送類型為L(zhǎng)AUNCH_ACTIVITY的消息,并將ActivityClientRecord 傳遞過去,sendMessage方法的代碼如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
   ...
      mH.sendMessage(msg);
  }

這里mH指的是H,它是ActivityThread的內(nèi)部類并繼承Handler,H的代碼如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

private class H extends Handler {
      public static final int LAUNCH_ACTIVITY         = 100;
      public static final int PAUSE_ACTIVITY          = 101;
...
public void handleMessage(Message msg) {
          if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
          switch (msg.what) {
              case LAUNCH_ACTIVITY: {
                  Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                  final ActivityClientRecord r = (ActivityClientRecord) msg.obj;//1
                  r.packageInfo = getPackageInfoNoCheck(
                          r.activityInfo.applicationInfo, r.compatInfo);//2
                  handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//3
                  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;
            ...
}

查看H的handleMessage方法中對(duì)LAUNCH_ACTIVITY的處理,在注釋1處將傳過來的msg的成員變量obj轉(zhuǎn)換為ActivityClientRecord。
在注釋2處通過getPackageInfoNoCheck方法獲得LoadedApk類型的對(duì)象并賦值給ActivityClientRecord 的成員變量packageInfo 。應(yīng)用程序進(jìn)程要啟動(dòng)Activity時(shí)需要將該Activity所屬的APK加載進(jìn)來,而LoadedApk就是用來描述已加載的APK文件。
在注釋3處調(diào)用handleLaunchActivity方法,代碼如下所示。
frameworks/base/core/java/android/app/ActivityThread.java

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
      Activity a = performLaunchActivity(r, customIntent);//1
      if (a != null) {
          r.createdConfig = new Configuration(mConfiguration);
          reportSizeConfigurations(r);
          Bundle oldState = r.state;
          handleResumeActivity(r.token, false, r.isForward,
                  !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);//2

          if (!r.activity.mFinished && r.startsNotResumed) {      
              performPauseActivityIfNeeded(r, reason);
              if (r.isPreHoneycomb()) {
                  r.state = oldState;
              }
          }
      } else {
          try {
              ActivityManagerNative.getDefault()
                  .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                          Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
          } catch (RemoteException ex) {
              throw ex.rethrowFromSystemServer();
          }
      }
  }

注釋1處的performLaunchActivity方法用來啟動(dòng)Activity ,注釋2處的代碼用來將Activity 的狀態(tài)置為Resume。如果該Activity為null則會(huì)通知ActivityManager停止啟動(dòng)Activity。來查看performLaunchActivity方法做了什么:
frameworks/base/core/java/android/app/ActivityThread.java

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  ...
        ActivityInfo aInfo = r.activityInfo;//1
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);//2
        }
        ComponentName component = r.intent.getComponent();//3
      ...
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);//4
           ...
            }
        } catch (Exception e) {
         ...
        }
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);//5

        ...
            if (activity != null) {
                Context appContext = createBaseContextForActivity(r, activity);//6
         ...
                }
                /**
                *7
                */
                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, window);

              ...
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//8
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
        }
        return activity;
}

注釋1處用來獲取ActivityInfo,在注釋2處獲取APK文件的描述類LoadedApk。注釋3處獲取要啟動(dòng)的Activity的ComponentName類,ComponentName類中保存了該Activity的包名和類名。注釋4處根據(jù)ComponentName中存儲(chǔ)的Activity類名,用類加載器來創(chuàng)建該Activity的實(shí)例。注釋5處用來創(chuàng)建Application,makeApplication方法內(nèi)部會(huì)調(diào)用Application的onCreate方法。注釋6處用來創(chuàng)建要啟動(dòng)Activity的上下文環(huán)境。注釋7處調(diào)用Activity的attach方法初始化Activity,attach方法中會(huì)創(chuàng)建Window對(duì)象(PhoneWindow)并與Activity自身進(jìn)行關(guān)聯(lián)。注釋8處會(huì)調(diào)用Instrumentation的callActivityOnCreate方法來啟動(dòng)Activity:
frameworks/base/core/java/android/app/Instrumentation.java

public void callActivityOnCreate(Activity activity, Bundle icicle,
         PersistableBundle persistentState) {
     prePerformCreate(activity);
     activity.performCreate(icicle, persistentState);//1
     postPerformCreate(activity);
 }

注釋1處調(diào)用了Activity的performCreate方法,代碼如下所示。
frameworks/base/core/java/android/app/Activity.java

final void performCreate(Bundle icicle) {
      restoreHasCurrentPermissionRequest(icicle);
      onCreate(icicle);
      mActivityTransitionState.readState(icicle);
      performCreateCommon();
  }

performCreate方法中會(huì)調(diào)用Activity的onCreate方法,這樣Activity就啟動(dòng)了,即應(yīng)用程序就啟動(dòng)了。

應(yīng)用程序啟動(dòng)過程就講到這里,最后附上ActivityThread啟動(dòng)Activity的時(shí)序圖
image.png
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容