Android系統源代碼情景分析筆記-Activity組件的啟動過程

Android系統源代碼情景分析筆記

Activity組件的啟動過程分析

[toc]

根Activity啟動的過程分析

Launcher組件啟動MainActivity的流程分析

  1. Launcher組件項ActivityManagerService發送一個啟動MainActivity組件的進程間通信請求
  2. ActivityManagerService首先將要啟動的MainActivity組件的信息保存下來,然后再向Launcher組件發送一個進入中止狀態的進程間通信請求
    3.Launcher組件進入到中止狀態之后,就會向ActivityManagerService發送一個已進入中止狀態的進程間通信請求,以便ActivityManagerService可以繼續執行啟動MainActivity組件的操作
    4.ActivityManagerService可以繼續執行啟動MainActivity組件的操作,但是要先講MainActiivty的宿主進程給創建出來,創建完成以后才能去進行啟動MainActivity組件的操作
    5.ActivityManagerService將啟動在第2步保存下來的MainActivity組件的信息發送給第4步創建的應用程序進程,以便它可以將MainActivity組件啟動起來
    總結整個流程圖大概如下:

    ![

啟動流程非常復雜,大概有35個步驟


setp1:Launcher.startActivitySafely

/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

public class Launcher extends Activity
    implements View.OnClickListener,OnLongClickListener,
    LauncherModel.Callbacks,View.OnTouchListener,
    PageSwitchListener,LauncherProviderChangeListener,
    LauncherStateTransitionAnimation.Callback{
        ...
        boolean startActivitySafely(View v, Intent intent, 
            Object tag) {
            boolean success = false;
            ...
            try {
             //調用startActivity方法去啟動應用的根Activity
               success = startActivity(v, intent, tag);
            } catch (ActivityNotFoundException e) {
               ...
            }
            return success;
        }
        ...
}    

首次啟動應用時候,會執行Launcher組件的startActivitySafely方法,要啟動應用的根Activity信息包含在參數intent重,可以看到這個方法主要調用了Launcher組件的startActivity方法,
/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

     private boolean startActivity(View v, Intent intent, 
         Object tag) {
         //添加啟動新的應用標識
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try{
            ...
            //
            startActivity(intent, optsBundle);
            ...
            return true;
        }cache(SecurityException e){
            ...
        }
        return false;

由于Launcher是Activity的子類,可以看到Launcher組件的startActivity最終調用了ActivitystartActivity方法

step2:Activity.startActivity

/frameworks/base/core/java/android/app/Activity.java

    public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback {
        ...
        @Override
        public void startActivity(Intent intent, 
            @Nullable Bundle options) {
            if (options != null) {
                startActivityForResult(intent, -1, options);
            } else {
                //最終也會調用到上面那個分支的函數
                startActivityForResult(intent, -1);
            }
        }
        ...
    }

這里調用了Activity組件的startActivityForResult,跟進如下

step3:Activity.startActivityForResult

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

mInstrumentation

這里看到調用了mInstrumentation.execStartActivity方法,Activity的成員變量mInstrumentation類型是Instrumentation,它是用來監控應用程序和系統之間交互操作。由于啟動Activity組件是應用程序與系統之間的一個交互操作,所以mInstrumentation.execStartActivity這個方法其實就是用來代理Activity啟動的操作,并且能夠監視整個交互的過程。

mMainThread.getApplicationThread()參數

Activity的成員變量mMainThread的類型為ActivityThread,用來描述一個應用程序進程。每當系統啟動一個應用程序進程時,都會在它里面加載一個ActivityThread類實例,并且會將這個ActivityThread類實例保存在每一個在該進程中啟動的Activity組件的父類Activity的成員變量mMainThread中。ActivityThread類的成員函數getApplicationThread用來獲取它內部的一個類型為ApplicationThread的Binder本地對象。mInstrumentation.execStartActivity方法中將ApplicationThread對象作為參數傳遞,這樣就可以把這個Binder對象傳遞給ActivityManagerService,因此ActivityManagerServcie接下來就可以通知Launcher組件進入Paused狀態了。

mToken參數

Activity類的成員變量mToken的類型是IBinder,它是一個Binder代理對象,指向了ActivityManagerService中一個類型為ActivityRecord的Binder本地對象。每一個已經啟動的Activity組件在ActivityManagerService中都有一個對應的的ActivityRecord對象,用來維護對應的Activity組件的運行狀態。mInstrumentation.execStartActivity方法中將將mToken作為參數傳遞,這樣接下來ActivityManagerService就能夠獲取到Launcher組件的詳細信息了。

setp4:Instrumentation.execStartActivity

/frameworks/base/core/java/android/app/Instrumentation.java

public class Instrumentation {
    ...
    public ActivityResult execStartActivity(Context who, 
        IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, 
        Bundle options){
            IApplicationThread whoThread = 
                (IApplicationThread) contextThread;
            ...
            try {
                ...
                int result = ActivityManagerNative.getDefault()
                    .startActivity(whoThread, 
                        who.getBasePackageName(),
                        intent,
                        intent.resolveTypeIfNeeded(
                        who.getContentResolver()),
                        token, 
                        target != null ? 
                        target.mEmbeddedID : null,
                        requestCode, 0, null, options);
               ...
            } catch (RemoteException e) {
               ...
            }
            ...
    }
    ...
}

可以看到Instrumentation.execStartActivity主要是調用ActivityManagerNative類的靜態成員函數getDefault獲取一個ActivityManagerService的代理對象,然后調用ActivityManagerNative的成員函數startActivity去啟動一個Activity組件

ActivityManagerNative.getDefault

/frameworks/base/core/java/android/app/ActivityManagerNative.java

public abstract class ActivityManagerNative extends Binder 
    implements IActivityManager{
        ...
        static public IActivityManager asInterface(IBinder obj) {
            if (obj == null) {
                return null;
            }
            IActivityManager in =
                (IActivityManager)obj.
                    queryLocalInterface(descriptor);
            if (in != null) {
                return in;
            }
    
            return new ActivityManagerProxy(obj);
        }
        
        private static final Singleton<IActivityManager> gDefault = 
            new Singleton<IActivityManager>() {
                protected IActivityManager create() {
                    IBinder b = ServiceManager.
                        getService("activity");
                    ...
                    IActivityManager am = asInterface(b);
                    ...
                    return am;
                }
        };
           
        static public IActivityManager getDefault() {
            return gDefault.get();
        }
        ...
}
  • 可以看到首次調用getDefalut時,實際上是通過ServiceManager去獲取一個名稱為“activity“的Java服務代理對象,也就是獲得了一個引用了ActivityManagerService的代理對象。那么接著調用asInterface將這代理對象封裝成一個ActivityManagerNativeProxy的代理對象,最后將其保存在成員變量gDefault中。這樣,以后再次調用ActivityManagerNative的成員函數getDefalut時,就可以直接獲得ActivityManagerService的一個代理對象。

step5:ActivityManagerProxy.startActivity

  • 回到Instrumentation.execStartActivity,現在我們知道了ActivityManagerNative.getDefault()實際上獲取的是一個ActivityManagerNativeProxy代理對象,那么實際上調用的也就它的startActivity方法
    /frameworks/base/core/java/android/app/ActivityManagerNative.java
public abstract class ActivityManagerNative extends Binder 
    implements IActivityManager{
    ...
    class ActivityManagerProxy implements IActivityManager{
            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);
                    //對應Activity中的mMainThread.getApplicationThread()
                    data.writeStrongBinder(caller != null ? 
                        caller.asBinder() : null);
                    //包名
                    data.writeString(callingPackage);
                    intent.writeToParcel(data, 0);
                    data.writeString(resolvedType);
                    //對應ActivityManagerService中的ActivityRecord
                    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);
                    reply.readException();
                    int result = reply.readInt();
                    reply.recycle();
                    data.recycle();
                    return result;
        }
    }
    ...
}

可以看到這個方法中,將前面傳遞過來的參數寫入到Parcel對象data中,然后再通過ActivityManagerNativeProxy類內部的一個Binder代理對象mRemote向ActivityManagerService發送一個類型為START_ACTIVITY_TRANSACTION的進程間通信請求。
這里面參數雖然非常多,但是需要注意的點參數只有三個,分別是callerintentresultTocaller指向的是Launcher組件所運行在的應用程序進程的Appication對象;intent包含了即將啟動的Activity組件信息;resultTo指向了ActivityManagerService內部的一個ActivityRecord對象,保存了Launcher組件的詳細信息。

ActivityManagerService處理進程通信指令

以上的5個步驟都是在Launcher進程中執行,接下來的6-12部是在ActivityManagerService中進行的,主要用來處理Launcher組件發出的START_ACTIVITY_TRANSACTION的進程間通信請求。如下圖所示:

image.png

step6:ActivityManagerService.startActivity

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
        ...
        @Override
        public final int startActivity(IApplicationThread caller, 
            String callingPackage,Intent intent, String resolvedType, 
            IBinder resultTo, String resultWho, int requestCode,int startFlags, 
            ProfilerInfo profilerInfo, Bundle options) {
                //caller是Launcher應用中對應的ApplicationThread代理對象
                //callingPackage包名
                //intent攜帶要啟動的Activity組件信息
                //resultTo指向ActivityRecord
                return startActivityAsUser(caller, callingPackage, intent, 
                    resolvedType, resultTo,resultWho, requestCode, startFlags, 
                    profilerInfo, options,UserHandle.getCallingUserId());
        }

        @Override
        public final int startActivityAsUser(IApplicationThread caller, 
            String callingPackage,Intent intent, String resolvedType, 
            IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId){
            ...
            userId = handleIncomingUser(Binder.getCallingPid(), 
                Binder.getCallingUid(),userId,false, ALLOW_FULL_ONLY, 
                "startActivity", null);
            // TODO: Switch to user app stacks here.
            return mStackSupervisor.startActivityMayWait(caller, -1, 
                callingPackage,intent,resolvedType, null, null, resultTo, 
                resultWho, requestCode, startFlags,profilerInfo, null, null, 
                options, false, userId, null, null);
        }
    ...
}

ActivityManagerService類的成員函數startActivity用來處理類型為START_ACTIVITY_TRANSACTION的進程間通信請求。
ActivityManagerService類有一個類型為ActivityStackSupervisor的成員變量mStackSupervisor,用來管理Activity組件的堆棧,上面ActivityManagerService.startActivityAsUser中最終調用的是ActivityStackSupervisor的startActivityMayWait,來進一步處理類型為START_ACTIVITY_TRANSACTION的進程間通信請求,即執行一個啟動Activity組件的操作。

setp7:ActivityStackSupervisor.startActivityMayWait

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

public final class ActivityStackSupervisor implements DisplayListener {
    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, WaitResult outResult, Configuration config,
        Bundle options, boolean ignoreTargetSecurity, int userId,
        IActivityContainer iContainer, TaskRecord inTask) {
           //解析Intent內容,獲取更多即將啟動的Activity的信息
           ...
           boolean componentSpecified = intent.getComponent() != null;

           // Don't modify the client's object!
           intent = new Intent(intent);
            
            // Collect information about the target of the Intent.
            ActivityInfo aInfo =
                    resolveActivity(intent, resolvedType, startFlags, 
                    profilerInfo, userId);
            ...
            synchronized (mService) {
                ...
                try {
                      ResolveInfo rInfo =
                          AppGlobals.getPackageManager().resolveIntent(
                                  intent, null,
                                  PackageManager.MATCH_DEFAULT_ONLY
                                  | ActivityManagerService.STOCK_PM_FLAGS, userId);
                      //將解析到的信息保存到類型為ActivityInfo的aInfo對象中
                      aInfo = rInfo != null ? rInfo.activityInfo : null;
                      aInfo = mService.getActivityInfoForUser(aInfo, userId);
                } catch (RemoteException e) {
                    ...
                }
                ...
            }
            
            //繼續執行啟動Activity組件的工作
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, 
                    options, ignoreTargetSecurity,
                    componentSpecified, null, container, inTask);
            ...
            return res;
        }
    }
    
    //解析Intent內容,并保存到aInfo中
    ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags,
            ProfilerInfo profilerInfo, int userId) {
        ActivityInfo aInfo;
        try {
            ResolveInfo rInfo =
                AppGlobals.getPackageManager().resolveIntent(
                        intent, resolvedType,
                        PackageManager.MATCH_DEFAULT_ONLY
                                    | ActivityManagerService.STOCK_PM_FLAGS, userId);
            aInfo = rInfo != null ? rInfo.activityInfo : null;
        } catch (RemoteException e) {
            ...
        }
        ...
        return aInfo;
    }
}    

上面這層的調用分為兩個部分:

  • 調用resolveActivity通過PackageManagerService服務區解析Intent參數的內容,獲取即將啟動的Activity組件更多的信息,接著將其存儲到類型為ActivityInfo的對象aInfo中
  • 調用startActivityLocked函數繼續執行啟動Activity組件的操作

step8:ActivityStackSupervisor.startActivityLocked

final int startActivityLocked(IApplicationThread caller,
    Intent intent, String resolvedType, ActivityInfo aInfo,
    IVoiceInteractionSession voiceSession, 
    IVoiceInteractor voiceInteractor,
    IBinder resultTo, String resultWho, int requestCode,
    int callingPid, int callingUid, String callingPackage,
    int realCallingPid, int realCallingUid, int startFlags, Bundle options,
    boolean ignoreTargetSecurity, boolean componentSpecified, 
    ActivityRecord[] outActivity,
    ActivityContainer container, TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;
        //獲取描述Launcher組件的ProcessRecord
        ProcessRecord callerApp = null;
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                ...
            }
        }
        ...
        //查找Launcher組件對應的ActivityRecord
        ActivityRecord sourceRecord = null;
        ...
        if (resultTo != null) {
            sourceRecord = isInAnyStackLocked(resultTo);
            ...
        }
        ...
        //創建描述即將啟動的Activity組件的ActivityRecord
        ActivityRecord r = new ActivityRecord(mService, callerApp, 
            callingUid, callingPackage, intent, resolvedType, aInfo, 
            mService.mConfiguration, resultRecord, resultWho, requestCode, 
            componentSpecified, voiceSession != null, this, container, options);
        ...
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, 
            voiceInteractor,startFlags, true, options, inTask);
        return err;
}

6.0下ActivityManagerService針對Activity堆棧存儲分類

/** Mapping from displayId to display current state */
private final SparseArray<ActivityDisplay> mActivityDisplays = new SparseArray<>();

 
// Exactly one of these classes per Display in the system. 
// Capable of holding zero or more
// attached {@link ActivityStack}s 
class ActivityDisplay {
    /** Actual Display this object tracks. */
    //對應的ID
    int mDisplayId;
    /** All of the stacks on this display. Order matters, topmost stack is in front of all other stacks, bottommost behind. Accessed directly by ActivityManager package classes */
    //Activity棧
    final ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
}

ActivityRecord isInAnyStackLocked(IBinder token) {
        int numDisplays = mActivityDisplays.size();
        for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.
                valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityRecord r = stacks.get(stackNdx).
                        isInStackLocked(token);
                if (r != null) {
                    return r;
                }
            }
        }
        return null;
}       
  • 在ActivityManagerService中,每一個應用程序進程都使用一個ProcessRecord對象來描述,并且保存在ActivityManaagerService內部。ActivityStackSupervisor類成員變量mService指向了ActivityManagerService,mService.getRecordForAppLocked(caller)根據caller獲取對應的一個ProcessRecord對象callerApp。由于caller對象指向的是Launcher組件所運行在的應用程序進程的一個ApplicationThread對象,所以,這里獲取到的ProcessRecord對象callerApp實際上就指向了Launcher組件所在的應用程序。接著callingPid = callerApp.pidcallingUid = callerApp.info.uid分別獲取到Launcher進程的PIDUID,并保存在callingPid和callingUid中。
  • 調用ActivityStackSupervisor的成員函數isInAnyStackLocked(resultTo)獲Launcher組件對應的Activity組件堆棧。在這個堆棧中,每一個已經啟動過的Activity組件都使用一個ActivityRecord對象來描述。前面提到,參數resultTo指向的是Launcher組件在ActivityManagerService中的一個ActivityRecord對象,因此,isInAnyStackLocked(resultTo)這個函數實際上就是從Activity組件堆棧存儲管理mActivityDisplays中找到用來描述Launcher組件的一個ActivityRecord對象,并保存在局部變量sourceRecord中。
  • 隨后創建了ActivityRecord對象r來描述即將啟動的Activity組件,即MainActivity
  • 現在ActivityStackSupervisor類中就得到了請求ActivityManagerService執行啟動Activity組件操作的源Activity組件(Launcher組件),以及要啟動的目標Activity組件信息(MainActivity組件),分別保存在ActivityRecord對象sourceRecord和r中。最后調用成員函數startActivityUncheckedLocked來進一步執行啟動目標Activity組件

setp9:ActivityStackSupervisor.startActivityUncheckedLocked

final int startActivityUncheckedLocked(final ActivityRecord r, 
    ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, 
    IVoiceInteractor voiceInteractor, int startFlags,boolean doResume, 
    Bundle options, TaskRecord inTask) {
        final Intent intent = r.intent;
        final int callingUid = r.launchedFromUid;
        ...
        //獲取目標Activity組件的啟動標識
        int launchFlags = intent.getFlags();
        ...
        // We'll invoke onUserLeaving before onPause only if the launching
        // activity did not explicitly state that this is an automated launch.
        //檢查是否由用戶手動啟動
        mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
        ...
        boolean addingToTask = false;
        ...
        ActivityStack sourceStack;
        ...
        boolean newTask = false;
        ...
         // Should this be considered a new task?
        if (r.resultTo == null && inTask == null && !addingToTask
                && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
                newTask = true;
                //創建或者計算將要啟動的Actiivty組件的專屬的TaskStack
                targetStack = computeStackFocus(r, newTask);
                targetStack.moveToFront("startingNewTask");
                ...
        }
        
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        return ActivityManager.START_SUCCESS;
}
  • int launchFlags = intent.getFlags()獲取目標的Activity組件的啟動標識位,并保存到局部變量launchFlags中。從step1中可以知道launchFlags = Intent.FLAG_ACTIVITY_NEW_TASK == 1,其他的均等于0
  • mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0檢查launchFlags是否等于1.如果等于1那么就表示目標Activity不是由用戶手動啟動的。如果目標Activity組件是由用戶手動啟動的,那么用來啟動它的源Activity組件就會獲得一個用戶離開事件通知。由于目標Activity組件是用戶在應用程序啟動器的界面上點擊啟動的,即變量launcherFlags的Intent.FLAG_ACTIVITY_NO_USER_ACTION == 0,因此,這里得到的mUserLeaving == true,表示后面要向源Activity組件發送一個用戶離開事件通知
  • 默認情況下,目標Activity組件與源Activity組件是運行在同一個任務中。如果Activity組件與目標Activity組件的啟動標識值的FLGAG_ACTIVITY_NEW_TASK被置為1,并且源Activity組件不需要知道目標Activity組件的運行結果,那么ActivityManagerService就將目標Activity組件運行在另外一個任務中。這個任務可能是一個新建的任務,也可能是一個存在的任務。Activity組件有一個android:taskAffinity屬性,用來描述它的一個專屬任務。當ActivityManagerService決定要將目標Activity組件運行在一個不同的任務中時,ActivityManagerService就會檢查目標Activity組件的專屬任務是否已經存在。如果存在,那么ActivityManagerService就會直接將目標Activity組件添加到它里面去運行;否則,就會線創建這個專屬任務,然后將目標Activity組件添加到它里面去運行
  • boolean addingToTask = falseaddingToTask的值初始化位false,表示要為目標Activity組件創建一個專屬任務,后續也會檢查這個專屬任務存在與否。如果存在,就會將addingToTask置為true
  • 從step2可知,源Activity組件是不需要知道目標Activity組件的執行結果的,即參數r的成員變量resultTo==null,因此,targetStack = computeStackFocus(r, newTask)回去創建一個新的專屬任務棧,并且賦值給targetStack(6.0實現比較復雜不去分析怎么管理這個任務),targetStack.moveToFront("startingNewTask")將其挪動到最頂層
  • 最后調用targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options)繼續執行啟動目標Activity的操作

ActivityStack.startActivityLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

1 final class ActivityStack {
2   ...
3   final void startActivityLocked(ActivityRecord r, boolean newTask,
4            boolean doResume, boolean keepCurTransition, Bundle options) {
        //獲取目標Activity的專屬任務描述TaskRecord
5       TaskRecord rTask = r.task;
6       final int taskId = rTask.taskId;
7        // mLaunchTaskBehind tasks get placed at the back of the task stack.
8        if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)){
9             // Last activity in task had been removed or ActivityManagerService 
10            //is reusing task.
11            // Insert or replace.
12            // Might not even be in.
13            insertTaskAtTop(rTask, r);
14            mWindowManager.moveTaskToTop(taskId);
15         }
16     }
17     ...
18     if (doResume) {
19           mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
20       }
21   ...
22 }
  • Activity用來描述一個應用到Activity堆棧信息.這里調用的Activity就是目標Activity的新建堆棧信息
  • 上面第5-16行代碼中,先獲取目標Activity的專屬任務描述TaskRecord:rTask,然后將這個任務插入任務棧頂部,之后將該任務移動到頂端
  • 從Step8可以知道傳入的doReusme = true,因此接下來會調用回ActivityStackSupervisor的resumeTopActivitiesLocked方法將Activity組件堆棧頂端的Activity組件激活,這個時候位于Activity組件堆棧頂端的Activity恰好就是將要啟動的Activity,也就是MainActivity。因為前面的操作正好將目標Activity組件插入到了Activity堆棧頂端

step10:ActivityStackSupervisor.resumeTopActivityLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

 boolean resumeTopActivitiesLocked(ActivityStack targetStack, 
    ActivityRecord target,Bundle targetOptions) {
    //上一步傳入的targetStack不會是null,所以這不會執行
    if (targetStack == null) {
       targetStack = mFocusedStack;
    }
    // Do targetStack first.
    boolean result = false;
    //由于目標Activity組件的堆棧已經在上一步置頂,所以會執行這里
    if (isFrontStack(targetStack)) {
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }
    //后續先不分析
    ...
    return result;
 }          
  • 追蹤發現這里又調用回了ActivityStack的成員函數resumeTopActivityLocked,繼續追蹤

ActivityStack.resumeTopActivityLocked

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    ...
    try{
        ...
        result = resumeTopActivityInnerLocked(prev, options);
    }finally{
    }
    ...
}

繼續跟進ActivityStack的成員函數resumeTopActivityInnerLocked

1 private boolean resumeTopActivityInnerLocked(ActivityRecord prev,Bundle options){
      //獲取待啟動的Activity組件
2     ...
3     // Find the first activity that is not finishing.
4     final ActivityRecord next = topRunningActivityLocked(null);
5    
6     // Remember how we'll process this pause/resume situation, 
7     // and ensure that the state is reset however we wind up proceeding.
8     final boolean userLeaving = mStackSupervisor.mUserLeaving;
9     mStackSupervisor.mUserLeaving = false;
10    ...
11    // If the top activity is the resumed one, nothing to do.
12    if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
13          mStackSupervisor.allResumedActivitiesComplete()) {
14       ...
15       return false;   
16   }
17    ...
18    // If we are sleeping, and there is no resumed activity, and the top
19    // activity is paused, well that is the state we want.
20    if (mService.isSleepingOrShuttingDown()
21            && mLastPausedActivity == next
22            && mStackSupervisor.allPausedActivitiesComplete()) {
23      // Make sure we have executed any pending transitions, since there
24      // should be nothing left to do at this point.
25      mWindowManager.executeAppTransition();
26      mNoAnimActivities.clear();
27      ActivityOptions.abort(options);
28      return false;
29    }
30    ...
31    // If we are currently pausing an activity, then don't do anything
32    // until that is done.
33    if (!mStackSupervisor.allPausedActivitiesComplete()) {
34        return false;
35    }
36    ...
37    // We need to start pausing the current activity so the top one
38    // can be resumed...
39    ...
40    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true,
41          dontWaitForPause);
42    if (mResumedActivity != null) {
43      ...
44      pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
45    }
46    if (pausing) {
47      return true;
48    }
49    ...
50 }
  • 第4行調用成員函數topRunningActivityLocked獲取當前Activity組件堆棧最上面的一個不是處于Finishing狀態的Activity的組件。在前面step9中,我們將MainActivity組件保存在當前Activity組件堆棧的頂端,并且它正處于等待啟動的狀態。因此。這里得到的ActivityRecord對象就指向了即將啟動的MainActivity組件
  • 第8-9行將ActivityStackSupervisor類成員變量mUserLeaving的值保存在變量userLeaving中,并將其置為false,因為接下來通過變量userLeaving的值就可以知道是否向源Activity組件發送一個用戶離開的事件通知
  • ActivityStack類有三個成員變量mResumedActivitymLastPausedActivitymPausingActivity,他們類型均為ActivityRecord,分別用來描述系統當前激活的Activity組件、上一次被中止的Activity組件,以及正在被中止的Activity組件
  • 第12-13行的if語句檢查即將要啟動的Activity組件是否等于當前被激活的Activity組件。如果等于,并且它的狀態為Resumed,那么可以直接返回false,表示要激活的Activity已經被激活過了。
  • 第20-23行的if語句檢查即將要啟動的Activity組件是否等于上一次被中止的Activity組件。如果等于,并且這個時候系統正要進入關機或者睡眠的狀態,那么這里也可以返回false,因為這個時候講目標Activity啟動起來是沒有任何意義的
  • 第33行的if語句檢查當前是否正在中止一個Activity組件。如果是,那么就要等到中止完成以后,再啟動Activity組件next,所以接下來return語句直接返回false
  • 系統當前正在激活的Activity組件是Launcher組件,即ActivityStack類的成員變量mResumedActivity指向了Launcher組件,因此第42行的mResumedActivity != null成立。接下來就會執行startPausingLocked(userLeaving, false, true, dontWaitForPause)來通知Launcher組件進入Paused狀態,以便他將焦點讓給即將要啟動的MainActivity組件。

step11:ActiviyStack.startPausingLocked

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, 
    boolean resuming,boolean dontWait) {
    ...
    //mResumedActivity當前指向的是Launcher組件
    ActivityRecord prev = mResumedActivity;
    ...
    mResumedActivity = null;
    mPausingActivity = prev;
    mLastPausedActivity = prev;
    ...
    prev.state = ActivityState.PAUSING;
    ...
    if (prev.app != null && prev.app.thread != null) {
        try {
            ...
            prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                userLeaving, prev.configChangeFlags, dontWait);
        } catch (Exception e) {
            ...
        }
    }else{
        ...
    }
    ...
    if (mPausingActivity != null) {
       ...
       if(dontWait){
            ...
       } else{
            // Have the window manager pause its key dispatching until the new
            // activity has started.  If we're pausing the activity just because
            // the screen is being turned off and the UI is sleeping, don't interrupt
            // key dispatch; the same activity will pick it up again on wakeup.
            Message msg = mHandler.obtainMessage(PAUSE_TIMEOUT_MSG);
            msg.obj = prev;
            prev.pauseTime = SystemClock.uptimeMillis();
            mHandler.sendMessageDelayed(msg, PAUSE_TIMEOUT);
            return true;
       }
   }else{
       ...
   }        
}
  • 這段代碼中首先將Activity對象pre、及ActivityStack類成員變量mPausingActivity和mLastPausedActivity指向即將要進入Paused狀態的Launcher組件,并且講成員變量mResumedActivity的值置為null。
  • ActivityRecord類有一個成員變量app,類型為ProcessRecord,用來描述一個Activity組件所運行在的應用程序進程;而ProcessRecord類又有一個成員變量thread,他的類型為ApplicationThreadProxy,用來描述一個Binder代理對象,引用的是一個類型為ApplicationThread的Binder本地對象。
  • 由于ActivityRecord對象pre指向的是即將要進入Paused狀態的Launcher組件,因此,prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);這段代碼實際上是向Launcher組件所運行在的應用程序發送一個中止Launcher組件的通知,以便Launcher組件有機會執行一些數據保存的操作。
  • Launcher組件處理完成ActivityManagerService發送過來的中止通知以后,必須再向ActivityManagerService發送一個啟動MainActivity組件的通知,以便ActivityManagerService可以將位于Activity組件堆棧頂端的MainActivity組件啟動起來。但是,ActivityManagerService不能無限地等待。因此,接下來會調用ActivityManagerService類的成員變量mHandler向ActivityManagerServcie所運行在的線程發送一條延時消息,該消息的類型為PAUSE_TIMEOUT_MSG,并且將在PAUSE_TIMEOUT == 500毫秒以后執行。如果Launcher組件不能在PAUSE_TIMEOUT毫秒內再向ActivityManagerService再次發送一個啟動MainActivity組件的通知,那么ActivityManagerService就會認為未響應。
  • 接下來繼續分析ApplicationThreadProxy類的成員函數schedulePauseActivity

step12:ApplicationThreadProxy.schedulePauseActivity

/frameworks/base/core/java/android/app/ApplicationThreadNative.java

public abstract class ApplicationThreadNative extends Binder
        implements IApplicationThread {
        ...
        class ApplicationThreadProxy implements IApplicationThread {
                ...
                public final void schedulePauseActivity(IBinder token, 
                    boolean finished, boolean userLeaving, int configChanges, 
                    boolean dontReport) throws RemoteException {
                        Parcel data = Parcel.obtain();
                        data.writeInterfaceToken(IApplicationThread.descriptor);
                        data.writeStrongBinder(token);
                        data.writeInt(finished ? 1 : 0);
                        data.writeInt(userLeaving ? 1 :0);
                        data.writeInt(configChanges);
                        data.writeInt(dontReport ? 1 : 0);
                        mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, 
                            null,IBinder.FLAG_ONEWAY);
                        data.recycle();
                }
                ...
        }
        ...
}
  • ApplicationThreadProxy.schedulePauseActivity中先將前面方法傳入的參數寫入到Parcel對象data中,然后再通過ApplicationThreadProxy類的一個內部Binder代理對象mRemote向Launcher組件所在的應用程序進程發送一個類型為SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進程間通訊請求
  • 以上7步都是在ActivityManagerService中執行的。

小總結

  • 分析到這里其實我們只分析了一小部分,但是總結起來整個流程大概是點擊桌面上應用圖標的入口,也就是調用Launcher組件的startActivity方法,會通過一系列的函數調用以后,向ActivityManagerService發送一個START_ACTIVITY_TRANSACTION的進程間指令,然后ActivityServcieManager收到該執行以后,回去解析準備即將要啟動Activity組件的詳細信息,并且創建其堆棧,將其堆棧置頂以后,然后再向Launcher組件發送一個SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進程間指令去修改Launcher組件的狀態為Paused。
  • 接下來的13-17步是在應用程序Launcher中執行的,主要是用來處理AcitivityManagerService發出的類型為SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進程間通信請求,如下圖:
    !](https://upload-images.jianshu.io/upload_images/2968643-b26d7cf0412fa3f7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

step13: ActivityThread.schedulePauseActivity

/frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread {
    ...
    private class ApplicationThread extends ApplicationThreadNative {
        ...
        public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                    configChanges);
        }
        ...
    }
    ...
}   
  • ApplicationThread類的成員函數schedulePauseActivity用來處理類型為SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進程間通信請求。
  • 從上一步傳來的參數finished和userLeaving分別為false和true,而參數token是一個Binder代理類對象,指向了ActivityManagerService中與Launcher組件對應的一個ActivityRecord對象
  • ApplicationThread.schedulePauseActivity中主要調用了ActivityThread類的成員函數sendMessage來向應用Launcher的主線程發送一個類型為PAUSE_ACTIVITY的消息

step13:ActivityThread.sendMessage

/frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread {
    ...
    final H mH = new H();
    ...
    private void sendMessage(int what, Object obj, int arg1, int arg2) {
        sendMessage(what, obj, arg1, arg2, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, 
        boolean async) {
        ...
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }
}   
  • ActivityThread類的成員變量mH是用來處理應用程序進程的主線程消息的,類型為H,繼承自Handler類。
  • 追蹤可以看到最終上一步發送的類型為PAUSE_ACTIVITY的消息最終是由H這個類來進行處理的

step15:H.handleMessage

/frameworks/base/core/java/android/app/ActivityThread.java

...
private class H extends Handler {

    ...
    public void handleMessage(Message msg) {
        ...
        switch (msg.what) {
            ...
            case PAUSE_ACTIVITY:
                ...
                handlePauseActivity((IBinder)msg.obj, false, 
                    (msg.arg1&1) != 0, msg.arg2,(msg.arg1&2) != 0);
                ...
                break;
            ...
        }   
        ...
    }
    ...
}
...
  • handlePauseActivity((IBinder)msg.obj, false, (msg.arg1&1) != 0, msg.arg2,(msg.arg1&2) != 0);這段代碼首先講Message對象msg的成員變量obj強轉成一個IBinder接口,因為它指向的是一個Binder代理對象,接著再調用ActivityThread類的成員函數handlePausedActivity來處理合格類型為PAUSE_ACTIVITY的消息

step16:ActivityThead.handlePauseActivity

public final class ActivityThread {
    ...
    final ArrayMap<IBinder, ActivityClientRecord> mActivities = 
            new ArrayMap<>();
    ...
    private void handlePauseActivity(IBinder token, boolean finished,
           boolean userLeaving, int configChanges, boolean dontReport) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                performUserLeavingActivity(r);
            }

            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(token, finished, r.isPreHoneycomb());

            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }

            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);
                } catch (RemoteException ex) {
                }
            }
            mSomeActivitiesChanged = true;
        }
    }
    ...
}
  • 在應用程序進程中啟動的每一個Activity組件都使用一個ActivityClientRecord對象來描述,這些ActivityClientRecrod對象對應于ActivityManagerService中的ActivityRecord對象,并且保存在ActivityThread類的成員變量mActivities中。
  • 從前面的調用過程可以知道,參數token指向的是ActivityManagerService中與Launcher組件對應的一個ActivityRecord對象,因此,ActivityClientRecord r = mActivities.get(token);就可以根據token直接在成員變量中找到一個用來描述Launcher組件的ActivityClientRecord對象。
  • 獲取了要中止的目標Activity組件之后,ActivityThread類的成員函數handlePauseActivity接下來做了三件事情。
    1.調用成員函數performUserLeavingActivity向Launcher組件發送一個用戶離開事件通知,即調用Launcher組件的成員函數onUserLeaveHint
    2.調用成員函數performPauseActivity向Launcher組件發送一個中止事件通知,即調用Launcher組件的成員函數onPause
    3.調用QueueWork類的靜態成員函數waitToFinish等待完成前面的一些數據寫入操作,例如,將數據寫入磁盤的操作。由于現在Launcher組件即將要進入Paused狀態了,因此就要保證Launcher組件前面所有數據寫入操作都處理完成;否則,等到Launcher組件重新進入Resumed狀態時,就無法恢復之前所保存的一些狀態數據。
  • 執行完以上三步以后,ActivityThread類的成員函數handlePauseActivity就初戀成ActivityManagerService發送過來的中止Launcher組件的進程間通信請求了。
  • 接下來ActivityManagerNative.getDefault().activityPaused(token);這段代碼調用ActivityManagerNative的靜態成員函數getDefault來獲得ActivityManagerService的一個代理對象,然后調用這個代理對象的成員函數activityPaused來通知ActivityManagerService,Launcher組件已經進入到Paused狀態了,因此,接下來就可以將MainActivity組件啟動起來了。

setp17:ActivityManagerProxy.activityPaused

ActivityManagerNative.getDefault()最終獲取得到的對象是一個類型為ActivityManagerProxy的對象
/frameworks/base/core/java/android/app/ActivityManagerNative.java

class ActivityManagerProxy implements IActivityManager{
    ...
    public void activityPaused(IBinder token) throws RemoteException{
       Parcel data = Parcel.obtain();
       Parcel reply = Parcel.obtain();
       data.writeInterfaceToken(IActivityManager.descriptor);
       data.writeStrongBinder(token);
       mRemote.transact(ACTIVITY_PAUSED_TRANSACTION, data, reply, 0);
       reply.readException();
       data.recycle();
       reply.recycle();
    }
    ...
}
  • ActivityManagerProxy的成員函數activityPaused先將前面傳入的參數寫入到Parcel對象data中,然后通過ActivityManagerProxy類內部的一個Binder代理對象mRemote向ActivityManagerService發送一個類型為ACTIVITY_PAUSED_TRANSACTION的進程間通信請求,如下圖所示:
    image.png

step18:ActivityManagerService.activityPaused

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ...
    @Override
    public final void activityPaused(IBinder token) {
        ...
        synchronized(this) {
            //根據傳入的token找到Launcher組件對應的ActivityStack
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        ...
    }
    ...
}
  • ActivityManagerService類成員函數activityPaused用來處理類型為ACTIVITY_PAUSED_TRANSTACTION的進程間通信請求

setp19:ActivityStack.activityPausedLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

final class ActivityStack {
    ...
    final void activityPausedLocked(IBinder token, boolean timeout) {
        ...
        final ActivityRecord r = isInStackLocked(token);
        if (r != null) {
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            if (mPausingActivity == r) {
                ...
                completePauseLocked(true);
            }else{
                ...
            }
        }
    }
    ...
}
  • final ActivityRecord r = isInStackLocked(token);這段代碼根據參數token的值查找Activity組件堆棧中與Launcher組件對應的ActivityRecord對象r
  • mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);這段代碼刪除ActivityManagerService中消息隊列處理PAUSE_TIMEOUT_MSG的消息。因為Launcher組件已經在規定的時間內處理完成ActivityManagerService發送過去的中止通知了
  • 前面在step11中將mPausingActivity指向了與Launcher組件對應的ActivityRecord對象,因此mPausingActivity == r判斷條件成立,緊接著調用completePauseLocked(true)來執行MainActivity組件的啟動操作

step20:ActivityStack.completePauseLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityStack.java

final class ActivityStack {
    ...
    private void completePauseLocked(boolean resumeNext) {
        //獲取Launcher組件對應的ActivityRecord
        ActivityRecord prev = mPausingActivity;
        if (prev != null) {
            prev.state = ActivityState.PAUSED;
            ...
            mPausingActivity = null;
        }
        //前面傳入的resumeNext == true
        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDown()) {
                mStackSupervisor.resumeTopActivitiesLocked(topStack, 
                    prev, null);
            }else{
                ...
            }
        }
    }
    ...
}
  • completePauseLocked函數首先獲取到Launcher組件對應的ActivityRecord對象并賦值給prev,修改prev的成員變量state為ActivityState.PAUSED,然后將ActivityStack的成員變量mPausingActivity置為null,表示系統當前正在中止的Activity組件已經進入到Paused狀態了
  • 由于上一步中傳入的resumeNext==true,因此if (resumeNext)成立,那么此時調用final ActivityStack topStack = mStackSupervisor.getFocusedStack();獲取最頂層的Activity組件堆棧,也就是即將要啟動的應用的Activity組件堆棧,緊接著!mService.isSleepingOrShuttingDown()判斷系統是否正在進入睡眠或者關閉狀態。如果不是,那么緊接著就調用ActivityStackSupervisor的成員函數resumeTopActivitiesLocked來啟動位于Activity組件堆棧頂端的Activity組件,也就是將要啟動的MainActivity組件。

ActivityStackSupervisor.resumeTopActivitiesLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

public final class ActivityStackSupervisor implements DisplayListener {
    ...
    boolean resumeTopActivitiesLocked(ActivityStack targetStack, 
        ActivityRecord target,Bundle targetOptions) {
        ...
        //targetStack上一步傳入也就是即將要啟動的應用的Activity組件堆棧
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }
        for (int displayNdx = mActivityDisplays.size() - 1; 
            displayNdx >= 0;--displayNdx) {
            final ArrayList<ActivityStack> stacks = 
                mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; 
                --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (stack == targetStack) {
                    // Already started above.
                    continue;
                }
                if (isFrontStack(stack)) {
                    stack.resumeTopActivityLocked(null);
                }
            }
        }
        return result;
    }   
    ...
}
  • ActivityStackSupervisor.resumeTopActivitiesLocked先判斷前面傳入的targetStack,也就是即將要啟動的Activity組件堆棧是否位于整個Activity堆棧管理的頂端,如果是就調用ActivityStack的成員函數resumeTopActivityLocked(target, targetOptions),如果不是就去找位于最頂端的Activity組件堆棧,然后調用該ActivityStack的成員函數resumeTopActivityLocked(null),繼續向下追蹤

ActivityStack.resumeTopActivityLocked

final boolean resumeTopActivityLocked(ActivityRecord prev) {
    return resumeTopActivityLocked(prev, null);
}

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    ...
    boolean result = false;
    try{
        ...
        result = resumeTopActivityInnerLocked(prev, options);
    }finally{
        ...
    }
    return result;
    ...
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, 
    Bundle options) {
    ...
    // Find the first activity that is not finishing.
    final ActivityRecord next = topRunningActivityLocked(null);
    ...
    
    // We need to start pausing the current activity so the top one
    // can be resumed...
    boolean dontWaitForPause = (next.info.flags&
        ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
    boolean pausing = mStackSupervisor.
        pauseBackStacks(userLeaving, true, dontWaitForPause);
    if (mResumedActivity != null) {
        ...
        pausing |= startPausingLocked(userLeaving, false, 
            true, dontWaitForPause);
    }
    if (pausing) {
        ...
        return true;
    }
    ...
    if (next.app != null && next.app.thread != null) {
        ...
    }else{
        ...
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    return true;
}    
  • 最終調用到了ActivityStack的成員函數resumeTopActivityInnerLocked,在前面step10中,ActivityManagerService已經調用過它的成員函數resumeTopActivityLocked來試圖啟動MainActivity組件了,但是由于那時候Launcher組件尚未進入Paused狀態,即ActivityStack類的成員變量mResumedActivity不等于null,因此,就會先調用成員函數startPasuingLocked來執行中止Launcher組件的操作
  • 在前面Step11中,ActivityManagerService在向Launcher組件發送中止通知之前,已經將ActivityStack類的成員變量mResumedActivity設置為null了,因此就會跳過startPausingLocked(userLeaving, false,true, dontWaitForPause);這段代碼的執行。
  • final ActivityRecord next = topRunningActivityLocked(null);這段代碼獲取位于Activity組件堆棧頂端的,與即將啟動的MainActivity組件對應的一個ActivityRecord對象next。由于此時MainActivity組件尚未被啟動起來,因此,next.app==null,接下來就會執行else分支,進而調用ActivityStackSupervisor的成員函數startSpecificActivityLocked

setp22:ActivityStackSupervisor.startSpecific

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

public final class ActivityStackSupervisor implements DisplayListener {
    ... 
    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig){
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        ...
        if (app != null && app.thread != null) {
            ...
            try{
                ...
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            }catch(RemoteException e){
                ...
            }
        }
        mService.startProcessLocked(r.processName, 
            r.info.applicationInfo, 
            true, 0,"activity", r.intent.getComponent(),
            false, false, true);
    } 
    ...          
}
  • 在ActivityManagerService中,每一個Activity組件都有一個用戶ID和一個進程名稱,其中,用戶ID是在安裝該Activity組件時由PackageManagerService分配的,而進程名稱則是由Activity 組件的android:process屬性來決定的。ActivityManagerService在啟動一個Activity 組件時候,首先會以他的用戶ID和進程名稱來檢查系統中是否存在一個對應的應用程序進程,如果存在,就會直接通知這個應用程序進程將該Activity組件啟動起來;否則,就會先以這個用戶ID和進程名稱來創建一個應用程序進程,然后再通知這個應用程序進程將該Activity組件啟動起來。
  • mService.getProcessLocked(r.processName,r.info.applicationInfo.uid, true);用來檢查在ActivityManagerService中與ActivityRecor對象r對應的Activity組件所需要的應用程序進程是否已經存在。如果存在就會先調用ActivityManagerService的成員函數realStackActivityLocked來啟動該Activity組件;否則就會先調用ActivityManagerService類的成員函數startProcessLocked為該Activity組件創建一個應用程序進程,然后再將其啟動起來
  • 由于MainActivity組件是第一次自動,即這時候系統是不可能存在所需要的應用程序進程的,因此,接下來就會調用ActivityManagerService類的成員函數startProcessLocked來為MainActivity組件創建一個應用程序進程

ActivityManagerService.startProcessLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
    implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ...
    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){
        ...
        ProcessRecord app;
        //前面傳入的islated = false
        if (!isolated) {
            //檢查請求的進程是否已經存在
            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
            ...
        else{
            ...
        }
        String hostingNameStr = hostingName != null
            ? hostingName.flattenToShortString() : null;
        if (app == null) {
            ...
            app = newProcessRecordLocked(info, processName, 
                isolated, isolatedUid);
            ...
        }else{
            ...
        }
        ...
        startProcessLocked(app, hostingType, hostingNameStr, 
            abiOverride, entryPoint, entryPointArgs);
        return (app.pid != 0) ? app : null;    
    }
    ...
}
  • 由于上一步傳入的islated = false,所以if (!isolated)判斷成立,所以緊接著調用getProcessRecordLocked(processName, info.uid, keepIfLarge)去檢查請求創建的進程是否已經存在,如果不存在緊接著調用newProcessRecordLocked(info, processName, isolated, isolatedUid);去創建一個ProcessRecordLocked對象,這個方法中最終會將其保存在ActivityManagerService類的成員變量mProcessNames中。
  • 最后調用另外一個重載函數startProcessLocked來創建一個應用進程,代碼如下:
/**
* All of the processes we currently have running organized by pid.
* The keys are the pid running the application.
*
* <p>NOTE: This object is protected by its own lock, NOT the global
* activity manager lock!
*/
final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();

private final void startProcessLocked(ProcessRecord app, 
    String hostingType,String hostingNameStr, String abiOverride, 
    String entryPoint, String[] entryPointArgs) {
    ...
    try{
        ...
        //獲取應用的uid
        int uid = app.uid;
        //獲取應用的用戶組id
        int[] gids = null;
        if (!app.isolated) {
                  int[] permGids = null;
                  try {
                      final IPackageManager pm = AppGlobals.
                      getPackageManager();
                      permGids = pm.
                       getPackageGids(app.info.packageName, app.userId);
                      MountServiceInternal mountServiceInternal = 
                       LocalServices.
                       getService(MountServiceInternal.class);
                      mountExternal = mountServiceInternal.
                       getExternalStorageMountMode(uid,
                              app.info.packageName);
                  } catch (RemoteException e) {
                      ...
                  }
            
                  // Add shared application and profile GIDs  
                  // so applications can share some
                  // resources like shared libraries and access 
                  // user-wide resources
                  if (ArrayUtils.isEmpty(permGids)) {
                      gids = new int[2];
                  } else {
                      gids = new int[permGids.length + 2];
                      System.arraycopy(permGids, 0, gids, 2, 
                       permGids.length);
                  }
                  gids[0] = UserHandle.
                   getSharedAppGid(UserHandle.getAppId(uid));
                  gids[1] = UserHandle.
                   getUserGid(UserHandle.getUserId(uid));
              }
            ...
    int debugFlags = 0;
    ...
    app.gids = gids;
    app.requiredAbi = requiredAbi;
    app.instructionSet = instructionSet;
    // Start the process.  It will either succeed and return a 
    // result containing
    // the PID of the new process, or else throw a RuntimeException.
    //前面傳入的entry==null = true
    boolean isActivityProcess = (entryPoint == null);
    //指定Process進程的入口
    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);
    ...
    app.setPid(startResult.pid);
    app.usingWrapper = startResult.usingWrapper;
    app.removed = false;
    app.killed = false;
    app.killedByAm = false;
    ...
    synchronized (mPidsSelfLocked) {
        this.mPidsSelfLocked.put(startResult.pid, app);
        if (isActivityProcess) {
             Message msg = mHandler.
                 obtainMessage(PROC_START_TIMEOUT_MSG);
                   msg.obj = app;
             mHandler.sendMessageDelayed(msg, 
                 startResult.usingWrapper
                 ? PROC_START_TIMEOUT_WITH_WRAPPER : 
                 PROC_START_TIMEOUT);
        }
    }
    ...
    }catch(RemoteException e){
        ...
    }
}
  • 上面這段代碼中首先要得到要創建的應用進程的用戶ID和用戶組ID,接著調用Process 類的靜態成員函數start來啟動一個新的應用程序進程。
  • 新的應用程序進程創建成功之后,當前進程就會得到一個大于0進程ID,保存在變量startResult中。接下來將信息保存到參數app中,并且將app所指向的的一個ProcessRecord對象保存在ActivityManagerService類的成員變量mPidsSelfLocked中。最后根據來向ActivityManagerService所在的線程消息對立發送一個類型為PROC_START_TIMEOUT_MSG的消息,并且startResult的成員變量usingWrapper來決定延遲時長是PROC_START_TIMEOUT_WITH_WRAPPER = 12001000毫秒,還是PROC_START_TIMEOUT = 101000**毫秒。
  • 新的應用程序必須在指定的時間內完成啟動工作,并且向ActivityManagerService發送一個啟動完成的通知,以便ActivityManagerService可以在啟動在該應用程序內部啟動一個Acivity組件;否則ActivityManagerService就會認為該應用程序啟動超時了,因此就不能將相應的Activity組件啟動起來
  • 前面在調用Process類的靜態成員函數start來啟動一個新的應用程序是,指定該進程的入口函數為android.app.ActivityThread類的靜態成員函數main,因此,接下來我們就從它開始分析新的應用程序的啟動過程


    image.png

step24:ActivityThread.main

/frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread {
    ...
    public static void main(String[] args) {
        ...
        //創建 消息循環
        Looper.prepareMainLooper();
        
        //創建ActivityThread并向ActivityManagerService發送一個啟動完成的通知
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        ...
        //通知完成以后當前進程進入消息循環的過程
        Looper.loop();
    }

    final ApplicationThread mAppThread = new ApplicationThread();

    private void attach(boolean system) {
        ...
        mSysytemThread = system;
        if(!system){
            ...
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            tyr{
                mgr.attachApplication(mAppThread);
            }catch(RemoteException ex){
                ...
            }
            ...
        }
        ...
    }   
    ...
}
  • 新的應用進程在啟動時,主要做了兩件事情
    1.在進程中創建一個ActivityThread對象,并且調用他的成員函數attach向ActivityManagerService發送一個啟動完成的通知
    2.調用Lopper類的靜態成員函數prepareMainLooper創建一個消息循環,并且在向ActivityManagerService發送啟動完成通知之后,使得當前進程進入到這個消息循環中

step25:ActivityManagerProxy.attachApplication

/frameworks/base/core/java/android/app/ActivityManagerNative.java

public abstract class ActivityManagerNative extends Binder implements IActivityManager{
    ...
    class ActivityManagerProxy implements IActivityManager{
        ...
        public void attachApplication(IApplicationThread app) 
            throws RemoteException{
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IActivityManager.descriptor);
            data.writeStrongBinder(app.asBinder());
            mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
            reply.readException();
            data.recycle();
            reply.recycle();
        }
        ...
        
    }
    ...

}
  • ActivityManagerProxy類的成員函數attachApplication中,首先將傳入的參數寫入到Parcel對象data中,然后通過ActivityManagerProxy類內部的一個Binder代理對象mRemote向ActivityManagerService發送一個ATTACH_APPLICATION_TRANSACTION的進程間通信請求
  • 以上2個步驟都是在新的應用程序進程中執行的,接下來的26-29步是在ActivityManagerService中執行的,主要用來處理新的應用程序進程發出的類型為ATTACH_APPLICATION_TRANSACTION的進程間通信請求,如下圖:
    image.png

step26:ActivityManagerService.attachApplication

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
    implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ...
    @Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }
    ...   
}
  • ActivityManagerService類的成員函數attachApplication接收到新的應用程序進程發送過來的類型為ATTACH_APPLICATION_TRANSCATION的進程間通信請求之后,他就知道了新的應用程序已經啟動完成了。因此,解析來就調用成員函數attachApplicationLocked來繼續執行啟動MainActivity組件的操作

step27:ActivityManagerService.attachApplicationLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative
    implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
    ...
    private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid) {
        
        // Find the application record that is being attached...  either via
        // the pid if we are running in multiple processes, or just pull the
        // next app record if we are emulating process with anonymous threads.
        ProcessRecord app;
        if (pid != MY_PID && pid >= 0) {
            synchronized (mPidsSelfLocked) {
                app = mPidsSelfLocked.get(pid);
            }
        }else{
            ...
        }
        ...
        final String processName = app.processName;
        ...
        //收集信息
        app.makeActive(thread, mProcessStats);
        app.curAdj = app.setAdj = -100;
        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
        app.forcingToForeground = null;
        updateProcessForegroundLocked(app, false, false);
        app.hasShownUi = false;
        app.debugging = false;
        app.cached = false;
        app.killedByAm = false;
        //移除進程啟動的消息
        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
        ...
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                ...
            }
        }
    }   
    ...   
}
  • 參數pid指向了前面所創建的應用進程的PID。在前面的step 23中,ActivityManagerService以這個PID為關鍵字將一個ProcessRecord對象保存在了成員比那里那個mPiedsSelfLocked中。因此app = mPidsSelfLocked.get(pid)可以通過參數pid直接將這個ProcessRecord取出來,并保存到局部變量app中
  • 前面的到的ProcessRecord對象app就是用來描述新創建的應用程序進程的。居然這個應用程序進程現在已經啟動起來了,那緊接著就可以對這個變量app進程一些初始化的操作,其中最重要的步驟是在app.makeActive(thread, mProcessStats)中,這里面的代碼最終將app持有的成員變量thread設置參數thread所指向的一個ApplicationThread代理對象,代碼簡單來說是這樣的public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {thread = _thread;};這樣ActivityManagerService就可以通過這個ApplicationThread代理對象來和新建的應用程序進行通信
  • 隨后調用mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);移除當前線程的消息隊列中類型為PROC_START_TIMEOUT_MSG的消息,因為新的應用程序進程已經在規定的時間內啟動起來了
  • 接下來調用mStackSupervisor.attachApplicationLocked(app)去判斷是否有新的Activity組件要啟動起來,跟進查看

ActivityStackSupervisor.attacApplication

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

public final class ActivityStackSupervisor implements DisplayListener {
    ...
    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; 
            --displayNdx) {
            ArrayList<ActivityStack> stacks = 
                mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack)) {
                    continue;
                }
                //找到即將要啟動的Activity組件
                ActivityRecord hr = stack.topRunningActivityLocked(null);
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            ...
                        }
                    }
                }
            }
        }
        ...
        return didSomething;
    }
    ...
}   
  • ActivityStackSupervisor的成員函數attacApplication首先循環便利所有維護的Activity組件堆棧,找到要啟動的MainActivity組件的堆棧,然后獲取位于棧頂的一個ActivityRecord對象r。接著檢查這個Activity組件的用戶ID和進程名是否于ProcessRecord對象app的所描述的應用程序進程的用戶ID和進程名一致。如果一致,那么說明ActiivtyRecord對象hr所描述的Activity組件是應用在ProcessRecord對象app所描述的應用程序進程中啟動的,因此,接下來就會調用ActivityStackSupervisor的成員函數realStartActivityLocked來請求改應用程序啟動一個Activity組件

step 28:ActivityStackSupervisor.realStartActivityLocked

/frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

public final class ActivityStackSupervisor implements DisplayListener {
    ...
    final boolean realStartActivityLocked(ActivityRecord r,
        ProcessRecord app, boolean andResume, boolean checkConfig)
        throws RemoteException {
        ...
        r.app = app;
        ...
        //將r所描述的Activity組件添加到參數app所描述的應用程序進程的Activity組件列表中
        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        ...
        try {
            ...
            List<ResultInfo> results = null;
            List<ReferrerIntent> newIntents = null;
            //上一步傳入的andResume == true
            if (andResume) {
                results = r.results;
                newIntents = r.newIntents;
            }
            ...
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                System.identityHashCode(r), r.info, 
                new Configuration(mService.mConfiguration),
                new Configuration(stack.mOverrideConfig), 
                r.compat, r.launchedFromPackage,task.voiceInteractor, 
                app.repProcState, r.icicle, r.persistentState, results,
                newIntents, !andResume, mService.isNextTransitionForward(), 
                profilerInfo);
            ...
        } catch (RemoteException e) {
        }
        ...
        return true;
    }
    ... 
}
  • ActivityStackSupervisor類的成員函數realStartActivityLocked中,首先將參數r的成員變量app的值設置為參數app,表示他描述的Activity組件是在參數app所描述的應用程序進程中啟動的,接下來將r所描述的Activity組件添加到參數app所描述的應用程序進程的Activity組件列表中
  • 完成前面的一系列準備工作以后,緊接著調用參數app的成員變量thread的成員函數scheduleLaunchActivity,來通知前面創建的應用程序進程啟動由參數r所描述的一個Activity組件,即MainActivity組件,接下來的調用流程圖如下


    image.png

step29:ApplicationThreadProxy.scheduleLaunchActivity

/frameworks/base/core/java/android/app/ActivityThread.java

final class ActivityThead{
    ...
    class ApplicationThreadProxy extends ApplicaionThreadNative{
        ...
         // we use token to identify this activity without having to send the
        // activity itself back to the activity manager. (matters more with ipc)
        @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) {
            ...
            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);
        }
        ...
    }
    ...
}
  • 可以看到這里將之前傳入的信息保存到一個ActiivtyRecordClient對象r中,然后發送一個類型為LAUNCH_ACTIVITY的消息給ActivityThread的內部類H進行處理

step 30:ActivityThread&&H.handleMessage

/frameworks/base/core/java/android/app/ActivityThread.java

final class ActivityThead{
    ...
    private class H extends Handler {
        ...
        public void handleMessage(Message msg) {
            ...
            switch (msg.what) {
                case LAUNCH_ACTIVITY:{
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                    //解析包名
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null);
                }break;
        }
    }
    ...
    
    public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (includeCode) {
                ref = mPackages.get(packageName);
            } else {
                ref = mResourcePackages.get(packageName);
            }
            return ref != null ? ref.get() : null;
        }
    }
}
  • 可以看到將前面傳入的消息進行解析,然后調用成員函數getPackageInfoNoCheck來獲得一個LoadedApk對象,并保存在ActivityRecord對象r的成員變量packageInfo中
  • 我們知道,每一個Android應用程序都是打包在一個Apk文件中的。一個Apk文件包含了一個Android應用程序的所有資源,應用程序進程在doing一個Activity組件時,需要將它的Apk文件加載進來,以便可以訪問它里面的資源。在ActivityThread類內部,就是用一個Loaded對象來描述一個已經加載的Apk文件
  • 最后調用ActivityThread類的成員函數handleLaunchActivity來啟動由ActiivtyClientRecord對象r所描述的一個Activity組件,即MainActivity組件。

step 31:ActivityThread.handlLaunchActivity

/frameworks/base/core/java/android/app/ActivityThread.java

final class ActivityThead{
    ...
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity a = performLaunchActivity(r, customIntent);
        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            //后續會引起一些列的onResume相關的生命周期相關的操作
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
            ..
        }else{
            // If there was an error, for any reason, tell the activity
            // manager to stop us.
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
            } catch (RemoteException ex) {
                // Ignore
            }
        }        
        ...
    }
    ...
}
  • ActivityThread類的成員函數handlLaunchActivity中首先調用成員函數performLaunchActivity將MainActivity啟動起來,接著調用成員函數handleResumeActivity將MainActivity組件的狀態置為Resumed,表示它是系統當前激活的Activity組件。
  • 記下來,我們就主要關注MainActiivty組件的啟動過程,即ActivityThread的成員函數performLaunchActivity的實現

step 32:ActivityThread.performLaunchActivity

/frameworks/base/core/java/android/app/ActivityThread.java

final class ActivityThead{
    ...
    private Activity performLaunchActivity(ActivityClientRecord r, 
        Intent customIntent){
        
        ...
        //獲取要啟動的MainActivity信息
        ComponentName component = r.intent.getComponent();
        ...
        //加載要啟動的MainActivity組件的類文件
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
            ...
        catch(Exception e){
            ...
        }     
    
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ...
            if (activity != null) {
                //創建上下文運行環境
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = 
                    r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                ...
                //基礎信息的保存
                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 (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, 
                        r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ...
            }
            ...
            mActivities.put(r.token, r);
        }catch(SuperNotCalledException e){
            ...
        }catch(Exception e){
            ...
        }
    }
    return activity;
}
  • ActivityThread類的成員函數perforeLaunchActivity手電調用ComponentName component = r.intent.getComponent();獲取要啟動的Activity組件的包名及類名,存儲到變量component中。接著將他的淚文件加載到內存中,并創建一個實例。由于所有的Activity組件都是從Activity類繼承下來的,我們就可以將前面創建的Activity組件保存在Activity對象activity中
  • 接下創建和初始化了一個ContextImpl對象appContext,用來作為前面所處創建的Activity對象activity的運行上下文環境,通過它就可以訪問到特定的應用程序資源,以及啟動其他的應用程序組件。接著使用ContextImpl對象appContext和ActivityClientRecord對象r來初始化Activity對象activity
  • Activity對象初始化完成之后,緊接著調用成員函數mInstrumentation的成員函數callActivityOnCreate將Activity對象啟動起來。在這個過程中,Activity對象actiivty的成員函數onCreate就會被調用。一般來說,我們在自定義一個Activity組件時,都會重寫其父類Activity的成員函數onCreate,以便可以加載自己的用戶界面,以及執行其他的一些業務相關的初始化操作
  • Activity對象activity啟動完成之后,緊接著就會以ActivityClientRecord對象r的成員變量token為關鍵字,將ActivityRecordClient對象r保存在ActivityThread類的成員變量mActivities中
  • 接下來就是我們經常看到的MainActivity的onCreate調用執行。至此MainActivity組件的啟動流程就分析完畢了。MainActivity組件作為應用程序的入口,它啟動起來就意味著整個應用程序便啟動起來了。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容