天天看點

Android開發知識(二十)Activity的啟動過程源碼追蹤,看看startActivity方法背後幹了什麼事前言涉及到的類如何檢視SDK中沒有的源檔案Activity啟動過程源碼追蹤Activity的冷啟動過程啟動流程回顧

文章目錄

  • 前言
  • 涉及到的類
  • 如何檢視SDK中沒有的源檔案
  • Activity啟動過程源碼追蹤
  • Activity的冷啟動過程
  • 啟動流程回顧

前言

我們特别熟悉當Activity需要跳轉到另外一個Activity的時候,直接用startActivity就可以了,那麼這句代碼的背後涉及到什麼,本篇将梳理一遍Activity的啟動過程,但是由于源碼篇幅過多,也比較複雜。沒辦法一一去解析源碼,隻能整理清楚這個主要流程。

涉及到的類

在梳理啟動流程之前,我先梳理了下涉及到的主要的以下這些類:

Instrumentation

ActivityManagerProxy

ActivityManagerNative

ActivityManagerService

ActivityStarter

ActivityStackSupervisor

ActivityStack

ApplicationThreadNative

ApplicationThreadProxy

ApplicationThread

ActivityThread

Process

RuntimeInit

LoadedApk

如何檢視SDK中沒有的源檔案

如果你手頭沒有一份Android的源碼,檢視不了一些SDK中沒有的類,那麼我強烈推薦你使用這個網站:http://androidxref.com

進去後選擇一個Android版本,比如我選擇的是Android 7.1.2:

Android開發知識(二十)Activity的啟動過程源碼追蹤,看看startActivity方法背後幹了什麼事前言涉及到的類如何檢視SDK中沒有的源檔案Activity啟動過程源碼追蹤Activity的冷啟動過程啟動流程回顧

查到源檔案,然後點進去之後就可以看了,這裡也推薦把他DownLoad下面然後放到Android Stduio上你的項目的随意的包下,這樣就可以通過AS來快速的跟蹤定位方法變量

Activity啟動過程源碼追蹤

從Activity的startActivity(Intent intent)開始

經過幾個方法重載後會調用到startActivityForResult():

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

startActivityForResult我們隻需要關注 if (mParent == null)的内容,因為ActivityGroup已經被廢棄了,現在一般都是用Activity+Fragment的方式

在if (mParent == null)裡面把邏輯移交到了Instrumentation的execStartActivity方法:

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
          //把contextThread強制轉成IApplicationThread,如此看出IApplicationThread也是一個IBinder子類,具體IApplicationThread是什麼看後面再說
        IApplicationThread whoThread = (IApplicationThread) contextThread;
        ...
        try {
           ...
           //把startActivity的邏輯移交到ActivityManager.getService()中,這裡的getService()就是AMS
            int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
             //檢查Activity的啟動結果
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }
           

這裡插播一下Instrumentation的這個checkStartActivityResult方法,他會檢查啟動Activity時産生的錯誤,在這裡抛出異常,比如我們熟悉的:have you declared this activity in your AndroidManifest.xm

我們看下ActivityManager.getService():

/**
     * @hide
     */
    public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    //擷取Activity Manager Service ,即AMS對象
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
           

IActivityManager是一個AIDL接口,它的一個實作是ActivityManagerProxy類,位于ActivityManagerNative(簡稱AMN)的一個内部類。

在這裡的時候要準備把邏輯移交給了AMS,由于不同程序,是以代理類來完成這個互動。

ActivityManagerProxy的startActivity方法:

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 {
        ...
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        ...
        return result;
    }
           

mRemote是則就是ActivityManagerNative,在bindler機制中,它的資料傳輸方法是這個transact方法,則對應于服務端則會同步執行onTranscat方法,

到這裡經過binder IPC過程,把邏輯移交到了system_server程序,ActivityManagerNative的onTransact中:

@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;
        }
        ...

           

ActivityManagerNative并沒有實作這裡的startActivity,它隻是個抽象類,而是由它的實作類ActivityManagerService(簡稱AMS)

那接下來就把Activity的啟動流程移交給了ActivityManagerService:

@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());
    }
           

隻是調用個重載方法,最後面的參數多傳了個UserHandle.getCallingUserId()調用了startActivityAsUser:

@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) {
        ...
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null);
    }
           

邏輯又移交到了ActivityStarter這個類,這裡要提到下,7.0之後的源碼,7.0之後才有這個類,而在7.0以下的版本,則是走了ActivityStackSupervisor

不過沒啥影響,既然是基于7.0 就按照7.0來

繼續追蹤ActivityStarter這個類調用的startActivityMayWait:

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) {

            //調用PackageManagerService完成intent解析
            ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
              ...:
               // Collect information about the target of the Intent.
             ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

            ...

             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);

               ...

            }
           

這個方法幾個重要的地方就是調用ActivityStackSupervisor都resolveIntent方法和resolveActivity方法

resolveIntent方法中最調用了:

ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
        try {
            //AppGlobals.getPackageManager()擷取PMS來完成intent解析
            return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
                    PackageManager.MATCH_DEFAULT_ONLY | flags
                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
        } catch (RemoteException e) {
        }
        return null;
    }
           

resolveIntent完成之後又調用了resolveActivity解析出ActivityInfo

最後調用了startActivityLocked:

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) {
	//對Activity啟動的權限檢查
       boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
                resultRecord, resultStack, options);
        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                callingPid, resolvedType, aInfo.applicationInfo);
                
	//為要啟動Activity建立ActivityRecord
	  ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
                intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
                requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
                options, sourceRecord);

}
           

,這個方法判斷了Intent中能不能正常找到相應的Component或者ActivityInfo、或者該Activity對目前使用者不可見,并且進行了各種對Activity的權限檢查。

然後接下來調用startActivityUnchecked,這個方法也很長:

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
            //前面各種對啟動模式和aunchFlag的邏輯解析
            ...


            //調用ActivityStack的startActivityLocked,完成WindowManager準備切換的相關流程
            mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
  if (mDoResume) {
            ...
            final ActivityRecord topTaskActivity = mStartActivity.task.topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
             ...
            } else {
            //最終調用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }

            }
           

startActivityUnchecked負責任務棧的的排程,會利用launchFlag和launchMode來判斷Activity所屬的Task棧,比如我們熟悉的singleTop、singleTask。還有另外一些Flag,如FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_CLEAR_TASK等

然後接下來調用ActivityStackSupervisor類的resumeFocusedStackTopActivityLocked方法:

boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
         //如果activity所屬棧位于前台,則用該task的resumeTopActivityUncheckedLocked
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        //task不在前台,調用目前前台棧的resumeTopActivityUncheckedLocked,傳遞的參數都是null
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || r.state != RESUMED) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        }
        return false;
    }
           

可以看到這個方法隻是判斷要跳轉的Activity所處的task是否位于前台,最後都是會調用到ActivityStack的resumeTopActivityUncheckedLocked的方法:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

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

經過一個判斷Activity是否已在前台後,走到resumeTopActivityInnerLocked方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    //系統沒有進入booting或booted狀态,則不允許啟動Activity
   if (!mService.mBooting && !mService.mBooted) {
             // Not ready yet!
             return false;
         }
    // Find the first activity that is not finishing.
     final ActivityRecord next = topRunningActivityLocked();

        if (next == null) {
                ...
         //找不到需要resume的Activity,則直接回到桌面
         return isOnHomeDisplay() &&
                 mStackSupervisor.resumeHomeStackTask(returnTaskType, prev, reason);
             }
        //mResumedActivity是上一次啟動的Activity
        if (mResumedActivity != null) {
            ```
           //通知上一個Activity進入pause狀态
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
        }
         if (pausing) {//已經暫停了
            ```
            if (next.app != null && next.app.thread != null) {
                //如果app已經啟動過
                //排程Activity所在程序的優先級,保證其不被kill
                mService.updateLruProcessLocked(next.app, true, null);
            }

        }
    mStackSupervisor.startSpecificActivityLocked(next, true, true);
 }
           

resumeTopActivityInnerLocked最主要就是判斷mResumedActivity存不存在,存在則pause,不存在則回到桌面

接下來調用了ActivityStackSupervisor的startSpecificActivityLocked方法:

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {

      //判斷activity所屬程序有沒有啟動
  ProcessRecord app = mService.getProcessRecordLocked(r.processName,
          r.info.applicationInfo.uid, true);
   r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                //下一步調用了這個方法
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }
        //如果沒有啟動程序,則先啟動
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);

 }
           

可以看出這個方法判斷了要跳轉的activity所在的app是否已經啟動過,沒有的話則需要建立程序後啟動activcity,有的話則走realStartActivityLocked方法

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
           //確定所有之前的activity都已經暫停完成
        if (!allPausedActivitiesComplete()) {
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }
        //調用IApplicationThread的scheduleLaunchActivity方法
         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);
        }
           

可以看得,最終的啟動過程又移交到IApplicationThread的scheduleLaunchActivity方法,而IApplicationThread的一個實作是ApplicationThreadProxy 代理類,是ApplicationThreadNative的一個内部類

我們看ApplicationThreadProxy的scheduleLaunchActivity方法:

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) throws RemoteException {
       ...
       //發送啟動的消息
        mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION, data, null,
                IBinder.FLAG_ONEWAY);
        data.recycle();
    }
           

這裡的mRemote是一個IBinder對象,時則就是指向ApplicationThreadNative,當執行transact的時候,對應的處理消息方法在:

@Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        switch (code) {
        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
                {
                    ...
                    scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                            referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                            notResumed, isForward, profilerInfo);
                    return true;
                }
       }
           

ApplicationThreadNative隻是一個抽象類,并沒有實作這個方法,它有一個實作類,就是ApplicationThread,該類位于ActivityThread的一個私有内部類中

進去檢視ActivityThread的scheduleLaunchActivity方法:

@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();

              ...

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }
           

最終可以執行了一個sendMessage方法,繼續追蹤發現這個方法最終調用的是ActivityThread的一個私有内部類H,它繼承了Handler

在這裡發送了一個消息是H.LAUNCH_ACTIVITY,那麼對應的在這個H類的handleMessage方法則有:

public void handleMessage(Message msg) {
 switch (msg.what) {
       case LAUNCH_ACTIVITY: {
       ...
       handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
       ...
   } break;
 }
 }
           

那邏輯就進入到ActivityThread的handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {

  //Activity經過performLaunchActivity方法被反射建立出來,這裡會執行onCreate方法
   Activity a = performLaunchActivity(r, customIntent);
   f (a != null) {
           //
           handleResumeActivity(r.token, false, r.isForward,
                   !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
  }
           

我們先來追蹤下performLaunchActivity:

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

 Activity activity = null;
         try {
             ClassLoader cl = r.packageInfo.getClassLoader();
             //通過Instrumentation的newActivity方法反射生成執行個體
             activity = mInstrumentation.newActivity(
                     cl, component.getClassName(), r.intent);
             ...
         } catch (Exception e) {
             ...
         }
    //調用LoadedAPK的makeApplication生成執行個體,或者傳回唯一執行個體
   Application app = r.packageInfo.makeApplication(false, mInstrumentation);
   `...
   if (activity != null) {
       //開始attach aactivity
       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);
       //執行了onCreate方法
    if (r.isPersistable()) {
                       mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                   } else {
                       mInstrumentation.callActivityOnCreate(activity, r.state);
                   }
      //執行了onStart方法
    if (!r.activity.mFinished) {
                   activity.performStart();
                   r.stopped = false;
               }
   }

   ...
 }
           

可以看到performLaunchActivity會執行Activity和反射建立以及Application的建立或者擷取,最後走了Activity的onCreate方法和onStart方法

Instrumentation的newActivity方法:

public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }
           

LoadedAPK的makeApplication方法:

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
         //如果已經有執行個體了 則直接傳回
        if (mApplication != null) {
            return mApplication;
        }
         ...

        Application app = null;

        try {
            ClassLoader cl = getClassLoader();
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //利用Instrumentation反射生成執行個體
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ...
        }
        mActivityThread.mAllApplications.add(app);
        //指派到mApplication,下次就不會再建立
        mApplication = app;
        if (instrumentation != null) {
            try {
               //這裡會讓Application執行onCreate方法
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
              ...
            }
        }
       ...
        return app;
    }
           

那麼我們接下來再分析下handleLaunchActivity方法中剩下的這個handleResumeActivity方法:

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
        ...
        //注意這個方法,會執行onResume方法
        r = performResumeActivity(token, clearHide, reason);
      //wm是wm是a.getWindowManager()擷取到,也就是WindowManagerImpl
      //在這個addView裡面建立了ViewRootImpl
    if (a.mVisibleFromClient && !a.mWindowAdded) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                }
    }
           

可以看得上面先是調用了performResumeActivity來走onResume這個周期,然後調用wm.addView(decor, l);來建立ViewRootImpl。

其中performResumeActivity方法裡面會執行activity.performResume();,在Activity的performResume方法中執行了onResume方法

而wm.addView(decor, l);這一句,wm就是a.getWindowManager()擷取到的,a是Activity,getWindowManager()就是傳回它的mWindowManger對象,而這個對象是WindowManagerImpl。

看下WindowManagerImpl的addView方法

@Override
    public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        applyDefaultToken(params);
        mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
    }
           

這裡的mGlobal就是WindowManagerGlobal,我們繼續追蹤這個WindowManagerGlobal.的addView方法:

public void addView(View view, ViewGroup.LayoutParams params,
                        Display display, Window parentWindow) {
        ...
       ViewRootImpl root;
       ...
       root = new ViewRootImpl(view.getContext(), display);
        try {
           root.setView(view, wparams, panelParentView);
       } catch (RuntimeException e) {
          ...
       }
  }
           

可以發現到ViewRootImpl其實是在WindowManagerGlobal中建立的,ViewRootImpl的setView方法

/**
 * We have one child
 */
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    synchronized (this) {
        if (mView == null) {
            mView = view;
            ...

            // Schedule the first layout -before- adding to the window
            // manager, to make sure we do the relayout before receiving
            // any other events from the system.
            requestLayout();

            ...

            view.assignParent(this);
            ...
        }
    }
}
           

可以看得到這裡會執行了requestLayout方法,說明頁面可擷取焦點,這也說明為什麼onResume後頁面才可以互動

Activity的冷啟動過程

回過頭去,我們在追蹤到startSpecificActivityLocked方法時說到,這個方法會判斷程序有沒有啟動,我們這裡隻是說到程序已經啟動的情況。當程序沒啟動時

會走:

mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
           

我們從ActivityManagerService的startProcessLocked方法入手:

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }


final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {


            ...

             startProcessLocked(
                            app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);


            ...

  }


 private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {

   ...
  if (entryPoint == null) entryPoint = "android.app.ActivityThread";
     Process.ProcessStartResult startResult = Process.start(entryPoint,
                       app.processName, uid, uid, gids, debugFlags, mountExternal,
                       app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                       app.info.dataDir, entryPointArgs);

   ...

 }
           

在AMS中經過一系列的startProcessLocked方法重載,最終到了這裡,會執行Process.start去建立一個新的程序,值得注意的是這個entryPoint,指向字元串:android.app.ActivityThread

在Process執行start方法中,如果一直追蹤下去,發現最終會去連接配接socket:

/**
     * Tries to open socket to Zygote process if not already open. If
     * already open, does nothing.  May block and retry.
     */
    private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            try {
                primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET);
            } catch (IOException ioe) {
                throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
            }
        }
        ...
    }

           

而連接配接的Socket是來自哪裡呢?就是ZygoteInit這個類,在系統啟動時便已經運作。它會開啟Socket服務,然後一直輪詢檢測有沒有client接入進來

private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {

  while (true) {
      ZygoteConnection newPeer = acceptCommandPeer(abiList);
  }
  }
           

在接收到新程序初始化的請求後,最終調用了RuntimeInit.zygoteInit方法:

public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        ...
        applicationInit(targetSdkVersion, argv, classLoader);
    }
           

接下來RuntimeInit的applicationInit方法:

private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {


        // Remaining arguments are passed to the start class's static main
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
    }

           

接下來RuntimeInit的invokeStaticMain方法:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws ZygoteInit.MethodAndArgsCaller {
        Class<?> cl;

        try {
            //裝載類,className就是我們前面傳入的android.app.ActivityThread
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

        Method m;
        try {
        //反射調用android.app.ActivityThread類的main方法
            m = cl.getMethod("main", new Class[] { String[].class });
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(
                    "Missing static main on " + className, ex);
        } catch (SecurityException ex) {
            throw new RuntimeException(
                    "Problem getting static main on " + className, ex);
        }

       ...
    }
           

由此最終就是建立了一個程序,然後在新的程序裡載入android.app.ActivityThread類,并執行它的main方法,我們知道,app啟動時會從它的main方法開始執行。

到這裡我們就大緻的過了一遍Activity的啟動流程了,包括冷啟動。

啟動流程回顧

這裡整理下啟動過程中會經曆的主要方法:

Activity#startActivity

Activity#startActivityForResult

Instrumentation#execStartActivity

ActivityManagerProxy#startActivity

ActivityManagerService#startActivity

ActivityManagerService#startActivityAsUser

ActivityStarter#startActivityMayWait

ActivityStarter#startActivityLocked

ActivityStarter#startActivityUnchecked

ActivityStackSupervisor#resumeFocusedStackTopActivityLocked

ActivityStack#resumeTopActivityUncheckedLocked

ActivityStack#resumeTopActivityInnerLocked

ActivityStackSuperviso#startSpecificActivityLocked

程序存在:

ActivityStackSuperviso#realStartActivityLocked

ApplicationThreadProxy#scheduleLaunchActivity

ApplicationThread#scheduleLaunchActivity

ActivityThread#handleLaunchActivity

ActivityThread#performLaunchActivity

ActivityThread#handleResumeActivity

ActivityThread#performResumeActivity

程序不存在:

ActivityManagerService#startProcessLocked

Process#start

RuntimeInit#zygoteInit

RuntimeInit#applicationInit

RuntimeInit#invokeStaticMain

終于完了,好累人的說。。