Android系統(tǒng)源代碼情景分析筆記-Activity組件的啟動(dòng)過程

Android系統(tǒng)源代碼情景分析筆記

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

[toc]

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

Launcher組件啟動(dòng)MainActivity的流程分析

  1. Launcher組件項(xiàng)ActivityManagerService發(fā)送一個(gè)啟動(dòng)MainActivity組件的進(jìn)程間通信請(qǐng)求
  2. ActivityManagerService首先將要啟動(dòng)的MainActivity組件的信息保存下來(lái),然后再向Launcher組件發(fā)送一個(gè)進(jìn)入中止?fàn)顟B(tài)的進(jìn)程間通信請(qǐng)求
    3.Launcher組件進(jìn)入到中止?fàn)顟B(tài)之后,就會(huì)向ActivityManagerService發(fā)送一個(gè)已進(jìn)入中止?fàn)顟B(tài)的進(jìn)程間通信請(qǐng)求,以便ActivityManagerService可以繼續(xù)執(zhí)行啟動(dòng)MainActivity組件的操作
    4.ActivityManagerService可以繼續(xù)執(zhí)行啟動(dòng)MainActivity組件的操作惕医,但是要先講MainActiivty的宿主進(jìn)程給創(chuàng)建出來(lái),創(chuàng)建完成以后才能去進(jìn)行啟動(dòng)MainActivity組件的操作
    5.ActivityManagerService將啟動(dòng)在第2步保存下來(lái)的MainActivity組件的信息發(fā)送給第4步創(chuàng)建的應(yīng)用程序進(jìn)程,以便它可以將MainActivity組件啟動(dòng)起來(lái)
    總結(jié)整個(gè)流程圖大概如下:

    ![

啟動(dòng)流程非常復(fù)雜,大概有35個(gè)步驟


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 {
             //調(diào)用startActivity方法去啟動(dòng)應(yīng)用的根Activity
               success = startActivity(v, intent, tag);
            } catch (ActivityNotFoundException e) {
               ...
            }
            return success;
        }
        ...
}    

首次啟動(dòng)應(yīng)用時(shí)候,會(huì)執(zhí)行Launcher組件的startActivitySafely方法妓笙,要啟動(dòng)應(yīng)用的根Activity信息包含在參數(shù)intent重,可以看到這個(gè)方法主要調(diào)用了Launcher組件的startActivity方法,
/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java

     private boolean startActivity(View v, Intent intent, 
         Object tag) {
         //添加啟動(dòng)新的應(yīng)用標(biāo)識(shí)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try{
            ...
            //
            startActivity(intent, optsBundle);
            ...
            return true;
        }cache(SecurityException e){
            ...
        }
        return false;

由于Launcher是Activity的子類,可以看到Launcher組件的startActivity最終調(diào)用了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 {
                //最終也會(huì)調(diào)用到上面那個(gè)分支的函數(shù)
                startActivityForResult(intent, -1);
            }
        }
        ...
    }

這里調(diào)用了Activity組件的startActivityForResult,跟進(jìn)如下

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

這里看到調(diào)用了mInstrumentation.execStartActivity方法,Activity的成員變量mInstrumentation類型是Instrumentation,它是用來(lái)監(jiān)控應(yīng)用程序和系統(tǒng)之間交互操作统锤。由于啟動(dòng)Activity組件是應(yīng)用程序與系統(tǒng)之間的一個(gè)交互操作,所以mInstrumentation.execStartActivity這個(gè)方法其實(shí)就是用來(lái)代理Activity啟動(dòng)的操作,并且能夠監(jiān)視整個(gè)交互的過程焕蹄。

mMainThread.getApplicationThread()參數(shù)

Activity的成員變量mMainThread的類型為ActivityThread船老,用來(lái)描述一個(gè)應(yīng)用程序進(jìn)程钾麸。每當(dāng)系統(tǒng)啟動(dòng)一個(gè)應(yīng)用程序進(jìn)程時(shí)钥平,都會(huì)在它里面加載一個(gè)ActivityThread類實(shí)例捷兰,并且會(huì)將這個(gè)ActivityThread類實(shí)例保存在每一個(gè)在該進(jìn)程中啟動(dòng)的Activity組件的父類Activity的成員變量mMainThread中。ActivityThread類的成員函數(shù)getApplicationThread用來(lái)獲取它內(nèi)部的一個(gè)類型為ApplicationThread的Binder本地對(duì)象。mInstrumentation.execStartActivity方法中將ApplicationThread對(duì)象作為參數(shù)傳遞,這樣就可以把這個(gè)Binder對(duì)象傳遞給ActivityManagerService,因此ActivityManagerServcie接下來(lái)就可以通知Launcher組件進(jìn)入Paused狀態(tài)了。

mToken參數(shù)

Activity類的成員變量mToken的類型是IBinder审残,它是一個(gè)Binder代理對(duì)象璧坟,指向了ActivityManagerService中一個(gè)類型為ActivityRecord的Binder本地對(duì)象励两。每一個(gè)已經(jīng)啟動(dòng)的Activity組件在ActivityManagerService中都有一個(gè)對(duì)應(yīng)的的ActivityRecord對(duì)象,用來(lái)維護(hù)對(duì)應(yīng)的Activity組件的運(yùn)行狀態(tài)当悔。mInstrumentation.execStartActivity方法中將將mToken作為參數(shù)傳遞,這樣接下來(lái)ActivityManagerService就能夠獲取到Launcher組件的詳細(xì)信息了傅瞻。

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主要是調(diào)用ActivityManagerNative類的靜態(tài)成員函數(shù)getDefault獲取一個(gè)ActivityManagerService的代理對(duì)象先鱼,然后調(diào)用ActivityManagerNative的成員函數(shù)startActivity去啟動(dòng)一個(gè)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();
        }
        ...
}
  • 可以看到首次調(diào)用getDefalut時(shí),實(shí)際上是通過ServiceManager去獲取一個(gè)名稱為“activity“的Java服務(wù)代理對(duì)象俭正,也就是獲得了一個(gè)引用了ActivityManagerService的代理對(duì)象奸鬓。那么接著調(diào)用asInterface將這代理對(duì)象封裝成一個(gè)ActivityManagerNativeProxy的代理對(duì)象,最后將其保存在成員變量gDefault中焙畔。這樣,以后再次調(diào)用ActivityManagerNative的成員函數(shù)getDefalut時(shí)串远,就可以直接獲得ActivityManagerService的一個(gè)代理對(duì)象宏多。

step5:ActivityManagerProxy.startActivity

  • 回到Instrumentation.execStartActivity,現(xiàn)在我們知道了ActivityManagerNative.getDefault()實(shí)際上獲取的是一個(gè)ActivityManagerNativeProxy代理對(duì)象,那么實(shí)際上調(diào)用的也就它的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);
                    //對(duì)應(yīng)Activity中的mMainThread.getApplicationThread()
                    data.writeStrongBinder(caller != null ? 
                        caller.asBinder() : null);
                    //包名
                    data.writeString(callingPackage);
                    intent.writeToParcel(data, 0);
                    data.writeString(resolvedType);
                    //對(duì)應(yīng)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;
        }
    }
    ...
}

可以看到這個(gè)方法中,將前面?zhèn)鬟f過來(lái)的參數(shù)寫入到Parcel對(duì)象data中,然后再通過ActivityManagerNativeProxy類內(nèi)部的一個(gè)Binder代理對(duì)象mRemote向ActivityManagerService發(fā)送一個(gè)類型為START_ACTIVITY_TRANSACTION的進(jìn)程間通信請(qǐng)求澡罚。
這里面參數(shù)雖然非常多,但是需要注意的點(diǎn)參數(shù)只有三個(gè)伸但,分別是callerintentresultTo留搔。caller指向的是Launcher組件所運(yùn)行在的應(yīng)用程序進(jìn)程的Appication對(duì)象更胖;intent包含了即將啟動(dòng)的Activity組件信息;resultTo指向了ActivityManagerService內(nèi)部的一個(gè)ActivityRecord對(duì)象隔显,保存了Launcher組件的詳細(xì)信息却妨。

ActivityManagerService處理進(jìn)程通信指令

以上的5個(gè)步驟都是在Launcher進(jìn)程中執(zhí)行,接下來(lái)的6-12部是在ActivityManagerService中進(jìn)行的,主要用來(lái)處理Launcher組件發(fā)出的START_ACTIVITY_TRANSACTION的進(jìn)程間通信請(qǐng)求括眠。如下圖所示:

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應(yīng)用中對(duì)應(yīng)的ApplicationThread代理對(duì)象
                //callingPackage包名
                //intent攜帶要啟動(dòng)的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類的成員函數(shù)startActivity用來(lái)處理類型為START_ACTIVITY_TRANSACTION的進(jìn)程間通信請(qǐng)求彪标。
ActivityManagerService類有一個(gè)類型為ActivityStackSupervisor的成員變量mStackSupervisor,用來(lái)管理Activity組件的堆棧掷豺,上面ActivityManagerService.startActivityAsUser中最終調(diào)用的是ActivityStackSupervisor的startActivityMayWait,來(lái)進(jìn)一步處理類型為START_ACTIVITY_TRANSACTION的進(jìn)程間通信請(qǐng)求,即執(zhí)行一個(gè)啟動(dòng)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內(nèi)容,獲取更多即將啟動(dòng)的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對(duì)象中
                      aInfo = rInfo != null ? rInfo.activityInfo : null;
                      aInfo = mService.getActivityInfoForUser(aInfo, userId);
                } catch (RemoteException e) {
                    ...
                }
                ...
            }
            
            //繼續(xù)執(zhí)行啟動(dòng)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內(nèi)容,并保存到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;
    }
}    

上面這層的調(diào)用分為兩個(gè)部分:

  • 調(diào)用resolveActivity通過PackageManagerService服務(wù)區(qū)解析Intent參數(shù)的內(nèi)容,獲取即將啟動(dòng)的Activity組件更多的信息,接著將其存儲(chǔ)到類型為ActivityInfo的對(duì)象aInfo中
  • 調(diào)用startActivityLocked函數(shù)繼續(xù)執(zhí)行啟動(dòng)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組件對(duì)應(yīng)的ActivityRecord
        ActivityRecord sourceRecord = null;
        ...
        if (resultTo != null) {
            sourceRecord = isInAnyStackLocked(resultTo);
            ...
        }
        ...
        //創(chuàng)建描述即將啟動(dòng)的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針對(duì)Activity堆棧存儲(chǔ)分類

/** 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. */
    //對(duì)應(yīng)的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中薄声,每一個(gè)應(yīng)用程序進(jìn)程都使用一個(gè)ProcessRecord對(duì)象來(lái)描述,并且保存在ActivityManaagerService內(nèi)部。ActivityStackSupervisor類成員變量mService指向了ActivityManagerService题画,mService.getRecordForAppLocked(caller)根據(jù)caller獲取對(duì)應(yīng)的一個(gè)ProcessRecord對(duì)象callerApp默辨。由于caller對(duì)象指向的是Launcher組件所運(yùn)行在的應(yīng)用程序進(jìn)程的一個(gè)ApplicationThread對(duì)象,所以苍息,這里獲取到的ProcessRecord對(duì)象callerApp實(shí)際上就指向了Launcher組件所在的應(yīng)用程序廓奕。接著callingPid = callerApp.pidcallingUid = callerApp.info.uid分別獲取到Launcher進(jìn)程的PIDUID档叔,并保存在callingPid和callingUid中桌粉。
  • 調(diào)用ActivityStackSupervisor的成員函數(shù)isInAnyStackLocked(resultTo)獲Launcher組件對(duì)應(yīng)的Activity組件堆棧。在這個(gè)堆棧中衙四,每一個(gè)已經(jīng)啟動(dòng)過的Activity組件都使用一個(gè)ActivityRecord對(duì)象來(lái)描述铃肯。前面提到,參數(shù)resultTo指向的是Launcher組件在ActivityManagerService中的一個(gè)ActivityRecord對(duì)象传蹈,因此押逼,isInAnyStackLocked(resultTo)這個(gè)函數(shù)實(shí)際上就是從Activity組件堆棧存儲(chǔ)管理mActivityDisplays中找到用來(lái)描述Launcher組件的一個(gè)ActivityRecord對(duì)象,并保存在局部變量sourceRecord中惦界。
  • 隨后創(chuàng)建了ActivityRecord對(duì)象r來(lái)描述即將啟動(dòng)的Activity組件挑格,即MainActivity
  • 現(xiàn)在ActivityStackSupervisor類中就得到了請(qǐng)求ActivityManagerService執(zhí)行啟動(dòng)Activity組件操作的源Activity組件(Launcher組件),以及要啟動(dòng)的目標(biāo)Activity組件信息(MainActivity組件)沾歪,分別保存在ActivityRecord對(duì)象sourceRecord和r中漂彤。最后調(diào)用成員函數(shù)startActivityUncheckedLocked來(lái)進(jìn)一步執(zhí)行啟動(dòng)目標(biāo)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;
        ...
        //獲取目標(biāo)Activity組件的啟動(dòng)標(biāo)識(shí)
        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.
        //檢查是否由用戶手動(dòng)啟動(dòng)
        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;
                //創(chuàng)建或者計(jì)算將要啟動(dòng)的Actiivty組件的專屬的TaskStack
                targetStack = computeStackFocus(r, newTask);
                targetStack.moveToFront("startingNewTask");
                ...
        }
        
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        return ActivityManager.START_SUCCESS;
}
  • int launchFlags = intent.getFlags()獲取目標(biāo)的Activity組件的啟動(dòng)標(biāo)識(shí)位,并保存到局部變量launchFlags中灾搏。從step1中可以知道launchFlags = Intent.FLAG_ACTIVITY_NEW_TASK == 1,其他的均等于0
  • mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0檢查launchFlags是否等于1.如果等于1那么就表示目標(biāo)Activity不是由用戶手動(dòng)啟動(dòng)的挫望。如果目標(biāo)Activity組件是由用戶手動(dòng)啟動(dòng)的,那么用來(lái)啟動(dòng)它的源Activity組件就會(huì)獲得一個(gè)用戶離開事件通知狂窑。由于目標(biāo)Activity組件是用戶在應(yīng)用程序啟動(dòng)器的界面上點(diǎn)擊啟動(dòng)的,即變量launcherFlags的Intent.FLAG_ACTIVITY_NO_USER_ACTION == 0媳板,因此,這里得到的mUserLeaving == true泉哈,表示后面要向源Activity組件發(fā)送一個(gè)用戶離開事件通知
  • 默認(rèn)情況下蛉幸,目標(biāo)Activity組件與源Activity組件是運(yùn)行在同一個(gè)任務(wù)中。如果Activity組件與目標(biāo)Activity組件的啟動(dòng)標(biāo)識(shí)值的FLGAG_ACTIVITY_NEW_TASK被置為1丛晦,并且源Activity組件不需要知道目標(biāo)Activity組件的運(yùn)行結(jié)果奕纫,那么ActivityManagerService就將目標(biāo)Activity組件運(yùn)行在另外一個(gè)任務(wù)中。這個(gè)任務(wù)可能是一個(gè)新建的任務(wù)采呐,也可能是一個(gè)存在的任務(wù)若锁。Activity組件有一個(gè)android:taskAffinity屬性,用來(lái)描述它的一個(gè)專屬任務(wù)斧吐。當(dāng)ActivityManagerService決定要將目標(biāo)Activity組件運(yùn)行在一個(gè)不同的任務(wù)中時(shí)又固,ActivityManagerService就會(huì)檢查目標(biāo)Activity組件的專屬任務(wù)是否已經(jīng)存在仲器。如果存在,那么ActivityManagerService就會(huì)直接將目標(biāo)Activity組件添加到它里面去運(yùn)行仰冠;否則乏冀,就會(huì)線創(chuàng)建這個(gè)專屬任務(wù),然后將目標(biāo)Activity組件添加到它里面去運(yùn)行
  • boolean addingToTask = falseaddingToTask的值初始化位false洋只,表示要為目標(biāo)Activity組件創(chuàng)建一個(gè)專屬任務(wù)辆沦,后續(xù)也會(huì)檢查這個(gè)專屬任務(wù)存在與否。如果存在识虚,就會(huì)將addingToTask置為true
  • 從step2可知肢扯,源Activity組件是不需要知道目標(biāo)Activity組件的執(zhí)行結(jié)果的,即參數(shù)r的成員變量resultTo==null担锤,因此蔚晨,targetStack = computeStackFocus(r, newTask)回去創(chuàng)建一個(gè)新的專屬任務(wù)棧,并且賦值給targetStack(6.0實(shí)現(xiàn)比較復(fù)雜不去分析怎么管理這個(gè)任務(wù)),targetStack.moveToFront("startingNewTask")將其挪動(dòng)到最頂層
  • 最后調(diào)用targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options)繼續(xù)執(zhí)行啟動(dòng)目標(biāo)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) {
        //獲取目標(biāo)Activity的專屬任務(wù)描述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用來(lái)描述一個(gè)應(yīng)用到Activity堆棧信息.這里調(diào)用的Activity就是目標(biāo)Activity的新建堆棧信息
  • 上面第5-16行代碼中肛循,先獲取目標(biāo)Activity的專屬任務(wù)描述TaskRecord:rTask,然后將這個(gè)任務(wù)插入任務(wù)棧頂部,之后將該任務(wù)移動(dòng)到頂端
  • 從Step8可以知道傳入的doReusme = true铭腕,因此接下來(lái)會(huì)調(diào)用回ActivityStackSupervisor的resumeTopActivitiesLocked方法將Activity組件堆棧頂端的Activity組件激活,這個(gè)時(shí)候位于Activity組件堆棧頂端的Activity恰好就是將要啟動(dòng)的Activity多糠,也就是MainActivity累舷。因?yàn)榍懊娴牟僮髡脤⒛繕?biāo)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不會(huì)是null,所以這不會(huì)執(zhí)行
    if (targetStack == null) {
       targetStack = mFocusedStack;
    }
    // Do targetStack first.
    boolean result = false;
    //由于目標(biāo)Activity組件的堆棧已經(jīng)在上一步置頂,所以會(huì)執(zhí)行這里
    if (isFrontStack(targetStack)) {
        result = targetStack.resumeTopActivityLocked(target, targetOptions);
    }
    //后續(xù)先不分析
    ...
    return result;
 }          
  • 追蹤發(fā)現(xiàn)這里又調(diào)用回了ActivityStack的成員函數(shù)resumeTopActivityLocked,繼續(xù)追蹤

ActivityStack.resumeTopActivityLocked

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

繼續(xù)跟進(jìn)ActivityStack的成員函數(shù)resumeTopActivityInnerLocked

1 private boolean resumeTopActivityInnerLocked(ActivityRecord prev,Bundle options){
      //獲取待啟動(dòng)的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行調(diào)用成員函數(shù)topRunningActivityLocked獲取當(dāng)前Activity組件堆棧最上面的一個(gè)不是處于Finishing狀態(tài)的Activity的組件。在前面step9中夹孔,我們將MainActivity組件保存在當(dāng)前Activity組件堆棧的頂端被盈,并且它正處于等待啟動(dòng)的狀態(tài)。因此析蝴。這里得到的ActivityRecord對(duì)象就指向了即將啟動(dòng)的MainActivity組件
  • 第8-9行將ActivityStackSupervisor類成員變量mUserLeaving的值保存在變量userLeaving中害捕,并將其置為false绿淋,因?yàn)榻酉聛?lái)通過變量userLeaving的值就可以知道是否向源Activity組件發(fā)送一個(gè)用戶離開的事件通知
  • ActivityStack類有三個(gè)成員變量mResumedActivity闷畸、mLastPausedActivitymPausingActivity,他們類型均為ActivityRecord吞滞,分別用來(lái)描述系統(tǒng)當(dāng)前激活的Activity組件佑菩、上一次被中止的Activity組件,以及正在被中止的Activity組件
  • 第12-13行的if語(yǔ)句檢查即將要啟動(dòng)的Activity組件是否等于當(dāng)前被激活的Activity組件裁赠。如果等于殿漠,并且它的狀態(tài)為Resumed,那么可以直接返回false佩捞,表示要激活的Activity已經(jīng)被激活過了绞幌。
  • 第20-23行的if語(yǔ)句檢查即將要啟動(dòng)的Activity組件是否等于上一次被中止的Activity組件。如果等于一忱,并且這個(gè)時(shí)候系統(tǒng)正要進(jìn)入關(guān)機(jī)或者睡眠的狀態(tài)莲蜘,那么這里也可以返回false谭确,因?yàn)檫@個(gè)時(shí)候講目標(biāo)Activity啟動(dòng)起來(lái)是沒有任何意義的
  • 第33行的if語(yǔ)句檢查當(dāng)前是否正在中止一個(gè)Activity組件。如果是票渠,那么就要等到中止完成以后逐哈,再啟動(dòng)Activity組件next,所以接下來(lái)return語(yǔ)句直接返回false
  • 系統(tǒng)當(dāng)前正在激活的Activity組件是Launcher組件问顷,即ActivityStack類的成員變量mResumedActivity指向了Launcher組件昂秃,因此第42行的mResumedActivity != null成立。接下來(lái)就會(huì)執(zhí)行startPausingLocked(userLeaving, false, true, dontWaitForPause)來(lái)通知Launcher組件進(jìn)入Paused狀態(tài)杜窄,以便他將焦點(diǎn)讓給即將要啟動(dòng)的MainActivity組件肠骆。

step11:ActiviyStack.startPausingLocked

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, 
    boolean resuming,boolean dontWait) {
    ...
    //mResumedActivity當(dāng)前指向的是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對(duì)象pre、及ActivityStack類成員變量mPausingActivity和mLastPausedActivity指向即將要進(jìn)入Paused狀態(tài)的Launcher組件塞耕,并且講成員變量mResumedActivity的值置為null哗戈。
  • ActivityRecord類有一個(gè)成員變量app,類型為ProcessRecord荷科,用來(lái)描述一個(gè)Activity組件所運(yùn)行在的應(yīng)用程序進(jìn)程唯咬;而ProcessRecord類又有一個(gè)成員變量thread,他的類型為ApplicationThreadProxy畏浆,用來(lái)描述一個(gè)Binder代理對(duì)象胆胰,引用的是一個(gè)類型為ApplicationThread的Binder本地對(duì)象。
  • 由于ActivityRecord對(duì)象pre指向的是即將要進(jìn)入Paused狀態(tài)的Launcher組件刻获,因此蜀涨,prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);這段代碼實(shí)際上是向Launcher組件所運(yùn)行在的應(yīng)用程序發(fā)送一個(gè)中止Launcher組件的通知,以便Launcher組件有機(jī)會(huì)執(zhí)行一些數(shù)據(jù)保存的操作蝎毡。
  • Launcher組件處理完成ActivityManagerService發(fā)送過來(lái)的中止通知以后厚柳,必須再向ActivityManagerService發(fā)送一個(gè)啟動(dòng)MainActivity組件的通知,以便ActivityManagerService可以將位于Activity組件堆棧頂端的MainActivity組件啟動(dòng)起來(lái)沐兵。但是别垮,ActivityManagerService不能無(wú)限地等待。因此扎谎,接下來(lái)會(huì)調(diào)用ActivityManagerService類的成員變量mHandler向ActivityManagerServcie所運(yùn)行在的線程發(fā)送一條延時(shí)消息碳想,該消息的類型為PAUSE_TIMEOUT_MSG,并且將在PAUSE_TIMEOUT == 500毫秒以后執(zhí)行毁靶。如果Launcher組件不能在PAUSE_TIMEOUT毫秒內(nèi)再向ActivityManagerService再次發(fā)送一個(gè)啟動(dòng)MainActivity組件的通知胧奔,那么ActivityManagerService就會(huì)認(rèn)為未響應(yīng)。
  • 接下來(lái)繼續(xù)分析ApplicationThreadProxy類的成員函數(shù)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中先將前面方法傳入的參數(shù)寫入到Parcel對(duì)象data中预吆,然后再通過ApplicationThreadProxy類的一個(gè)內(nèi)部Binder代理對(duì)象mRemote向Launcher組件所在的應(yīng)用程序進(jìn)程發(fā)送一個(gè)類型為SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進(jìn)程間通訊請(qǐng)求
  • 以上7步都是在ActivityManagerService中執(zhí)行的龙填。

小總結(jié)

  • 分析到這里其實(shí)我們只分析了一小部分,但是總結(jié)起來(lái)整個(gè)流程大概是點(diǎn)擊桌面上應(yīng)用圖標(biāo)的入口,也就是調(diào)用Launcher組件的startActivity方法,會(huì)通過一系列的函數(shù)調(diào)用以后,向ActivityManagerService發(fā)送一個(gè)START_ACTIVITY_TRANSACTION的進(jìn)程間指令,然后ActivityServcieManager收到該執(zhí)行以后,回去解析準(zhǔn)備即將要啟動(dòng)Activity組件的詳細(xì)信息,并且創(chuàng)建其堆棧,將其堆棧置頂以后岩遗,然后再向Launcher組件發(fā)送一個(gè)SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進(jìn)程間指令去修改Launcher組件的狀態(tài)為Paused胶背。
  • 接下來(lái)的13-17步是在應(yīng)用程序Launcher中執(zhí)行的,主要是用來(lái)處理AcitivityManagerService發(fā)出的類型為SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進(jìn)程間通信請(qǐng)求喘先,如下圖:
    !](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類的成員函數(shù)schedulePauseActivity用來(lái)處理類型為SCHEDULE_PAUSE_ACTIVITY_TRANSACTION的進(jìn)程間通信請(qǐng)求钳吟。
  • 從上一步傳來(lái)的參數(shù)finished和userLeaving分別為false和true,而參數(shù)token是一個(gè)Binder代理類對(duì)象窘拯,指向了ActivityManagerService中與Launcher組件對(duì)應(yīng)的一個(gè)ActivityRecord對(duì)象
  • ApplicationThread.schedulePauseActivity中主要調(diào)用了ActivityThread類的成員函數(shù)sendMessage來(lái)向應(yīng)用Launcher的主線程發(fā)送一個(gè)類型為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是用來(lái)處理應(yīng)用程序進(jìn)程的主線程消息的红且,類型為H,繼承自Handler類涤姊。
  • 追蹤可以看到最終上一步發(fā)送的類型為PAUSE_ACTIVITY的消息最終是由H這個(gè)類來(lái)進(jìn)行處理的

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對(duì)象msg的成員變量obj強(qiáng)轉(zhuǎn)成一個(gè)IBinder接口暇番,因?yàn)樗赶虻氖且粋€(gè)Binder代理對(duì)象,接著再調(diào)用ActivityThread類的成員函數(shù)handlePausedActivity來(lái)處理合格類型為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;
        }
    }
    ...
}
  • 在應(yīng)用程序進(jìn)程中啟動(dòng)的每一個(gè)Activity組件都使用一個(gè)ActivityClientRecord對(duì)象來(lái)描述思喊,這些ActivityClientRecrod對(duì)象對(duì)應(yīng)于ActivityManagerService中的ActivityRecord對(duì)象壁酬,并且保存在ActivityThread類的成員變量mActivities中。
  • 從前面的調(diào)用過程可以知道恨课,參數(shù)token指向的是ActivityManagerService中與Launcher組件對(duì)應(yīng)的一個(gè)ActivityRecord對(duì)象舆乔,因此,ActivityClientRecord r = mActivities.get(token);就可以根據(jù)token直接在成員變量中找到一個(gè)用來(lái)描述Launcher組件的ActivityClientRecord對(duì)象剂公。
  • 獲取了要中止的目標(biāo)Activity組件之后希俩,ActivityThread類的成員函數(shù)handlePauseActivity接下來(lái)做了三件事情。
    1.調(diào)用成員函數(shù)performUserLeavingActivity向Launcher組件發(fā)送一個(gè)用戶離開事件通知纲辽,即調(diào)用Launcher組件的成員函數(shù)onUserLeaveHint
    2.調(diào)用成員函數(shù)performPauseActivity向Launcher組件發(fā)送一個(gè)中止事件通知颜武,即調(diào)用Launcher組件的成員函數(shù)onPause
    3.調(diào)用QueueWork類的靜態(tài)成員函數(shù)waitToFinish等待完成前面的一些數(shù)據(jù)寫入操作,例如拖吼,將數(shù)據(jù)寫入磁盤的操作鳞上。由于現(xiàn)在Launcher組件即將要進(jìn)入Paused狀態(tài)了,因此就要保證Launcher組件前面所有數(shù)據(jù)寫入操作都處理完成吊档;否則篙议,等到Launcher組件重新進(jìn)入Resumed狀態(tài)時(shí),就無(wú)法恢復(fù)之前所保存的一些狀態(tài)數(shù)據(jù)籍铁。
  • 執(zhí)行完以上三步以后涡上,ActivityThread類的成員函數(shù)handlePauseActivity就初戀成ActivityManagerService發(fā)送過來(lái)的中止Launcher組件的進(jìn)程間通信請(qǐng)求了。
  • 接下來(lái)ActivityManagerNative.getDefault().activityPaused(token);這段代碼調(diào)用ActivityManagerNative的靜態(tài)成員函數(shù)getDefault來(lái)獲得ActivityManagerService的一個(gè)代理對(duì)象拒名,然后調(diào)用這個(gè)代理對(duì)象的成員函數(shù)activityPaused來(lái)通知ActivityManagerService,Launcher組件已經(jīng)進(jìn)入到Paused狀態(tài)了芋酌,因此增显,接下來(lái)就可以將MainActivity組件啟動(dòng)起來(lái)了。

setp17:ActivityManagerProxy.activityPaused

ActivityManagerNative.getDefault()最終獲取得到的對(duì)象是一個(gè)類型為ActivityManagerProxy的對(duì)象
/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的成員函數(shù)activityPaused先將前面?zhèn)魅氲膮?shù)寫入到Parcel對(duì)象data中,然后通過ActivityManagerProxy類內(nèi)部的一個(gè)Binder代理對(duì)象mRemote向ActivityManagerService發(fā)送一個(gè)類型為ACTIVITY_PAUSED_TRANSACTION的進(jìn)程間通信請(qǐng)求同云,如下圖所示:
    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) {
            //根據(jù)傳入的token找到Launcher組件對(duì)應(yīng)的ActivityStack
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        ...
    }
    ...
}
  • ActivityManagerService類成員函數(shù)activityPaused用來(lái)處理類型為ACTIVITY_PAUSED_TRANSTACTION的進(jìn)程間通信請(qǐng)求

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);這段代碼根據(jù)參數(shù)token的值查找Activity組件堆棧中與Launcher組件對(duì)應(yīng)的ActivityRecord對(duì)象r
  • mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);這段代碼刪除ActivityManagerService中消息隊(duì)列處理PAUSE_TIMEOUT_MSG的消息糖权。因?yàn)長(zhǎng)auncher組件已經(jīng)在規(guī)定的時(shí)間內(nèi)處理完成ActivityManagerService發(fā)送過去的中止通知了
  • 前面在step11中將mPausingActivity指向了與Launcher組件對(duì)應(yīng)的ActivityRecord對(duì)象,因此mPausingActivity == r判斷條件成立炸站,緊接著調(diào)用completePauseLocked(true)來(lái)執(zhí)行MainActivity組件的啟動(dòng)操作

step20:ActivityStack.completePauseLocked

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

final class ActivityStack {
    ...
    private void completePauseLocked(boolean resumeNext) {
        //獲取Launcher組件對(duì)應(yīng)的ActivityRecord
        ActivityRecord prev = mPausingActivity;
        if (prev != null) {
            prev.state = ActivityState.PAUSED;
            ...
            mPausingActivity = null;
        }
        //前面?zhèn)魅氲膔esumeNext == true
        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDown()) {
                mStackSupervisor.resumeTopActivitiesLocked(topStack, 
                    prev, null);
            }else{
                ...
            }
        }
    }
    ...
}
  • completePauseLocked函數(shù)首先獲取到Launcher組件對(duì)應(yīng)的ActivityRecord對(duì)象并賦值給prev星澳,修改prev的成員變量state為ActivityState.PAUSED,然后將ActivityStack的成員變量mPausingActivity置為null旱易,表示系統(tǒng)當(dāng)前正在中止的Activity組件已經(jīng)進(jìn)入到Paused狀態(tài)了
  • 由于上一步中傳入的resumeNext==true禁偎,因此if (resumeNext)成立,那么此時(shí)調(diào)用final ActivityStack topStack = mStackSupervisor.getFocusedStack();獲取最頂層的Activity組件堆棧,也就是即將要啟動(dòng)的應(yīng)用的Activity組件堆棧阀坏,緊接著!mService.isSleepingOrShuttingDown()判斷系統(tǒng)是否正在進(jìn)入睡眠或者關(guān)閉狀態(tài)如暖。如果不是,那么緊接著就調(diào)用ActivityStackSupervisor的成員函數(shù)resumeTopActivitiesLocked來(lái)啟動(dòng)位于Activity組件堆棧頂端的Activity組件忌堂,也就是將要啟動(dòng)的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上一步傳入也就是即將要啟動(dòng)的應(yīng)用的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先判斷前面?zhèn)魅氲膖argetStack,也就是即將要啟動(dòng)的Activity組件堆棧是否位于整個(gè)Activity堆棧管理的頂端士修,如果是就調(diào)用ActivityStack的成員函數(shù)resumeTopActivityLocked(target, targetOptions)枷遂,如果不是就去找位于最頂端的Activity組件堆棧,然后調(diào)用該ActivityStack的成員函數(shù)resumeTopActivityLocked(null)棋嘲,繼續(xù)向下追蹤

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;
}    
  • 最終調(diào)用到了ActivityStack的成員函數(shù)resumeTopActivityInnerLocked,在前面step10中登淘,ActivityManagerService已經(jīng)調(diào)用過它的成員函數(shù)resumeTopActivityLocked來(lái)試圖啟動(dòng)MainActivity組件了,但是由于那時(shí)候Launcher組件尚未進(jìn)入Paused狀態(tài)封字,即ActivityStack類的成員變量mResumedActivity不等于null黔州,因此,就會(huì)先調(diào)用成員函數(shù)startPasuingLocked來(lái)執(zhí)行中止Launcher組件的操作
  • 在前面Step11中阔籽,ActivityManagerService在向Launcher組件發(fā)送中止通知之前流妻,已經(jīng)將ActivityStack類的成員變量mResumedActivity設(shè)置為null了,因此就會(huì)跳過startPausingLocked(userLeaving, false,true, dontWaitForPause);這段代碼的執(zhí)行笆制。
  • final ActivityRecord next = topRunningActivityLocked(null);這段代碼獲取位于Activity組件堆棧頂端的绅这,與即將啟動(dòng)的MainActivity組件對(duì)應(yīng)的一個(gè)ActivityRecord對(duì)象next。由于此時(shí)MainActivity組件尚未被啟動(dòng)起來(lái)在辆,因此证薇,next.app==null,接下來(lái)就會(huì)執(zhí)行else分支,進(jìn)而調(diào)用ActivityStackSupervisor的成員函數(shù)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中匆篓,每一個(gè)Activity組件都有一個(gè)用戶ID和一個(gè)進(jìn)程名稱浑度,其中,用戶ID是在安裝該Activity組件時(shí)由PackageManagerService分配的鸦概,而進(jìn)程名稱則是由Activity 組件的android:process屬性來(lái)決定的箩张。ActivityManagerService在啟動(dòng)一個(gè)Activity 組件時(shí)候,首先會(huì)以他的用戶ID和進(jìn)程名稱來(lái)檢查系統(tǒng)中是否存在一個(gè)對(duì)應(yīng)的應(yīng)用程序進(jìn)程,如果存在先慷,就會(huì)直接通知這個(gè)應(yīng)用程序進(jìn)程將該Activity組件啟動(dòng)起來(lái)饮笛;否則,就會(huì)先以這個(gè)用戶ID和進(jìn)程名稱來(lái)創(chuàng)建一個(gè)應(yīng)用程序進(jìn)程论熙,然后再通知這個(gè)應(yīng)用程序進(jìn)程將該Activity組件啟動(dòng)起來(lái)福青。
  • mService.getProcessLocked(r.processName,r.info.applicationInfo.uid, true);用來(lái)檢查在ActivityManagerService中與ActivityRecor對(duì)象r對(duì)應(yīng)的Activity組件所需要的應(yīng)用程序進(jìn)程是否已經(jīng)存在。如果存在就會(huì)先調(diào)用ActivityManagerService的成員函數(shù)realStackActivityLocked來(lái)啟動(dòng)該Activity組件脓诡;否則就會(huì)先調(diào)用ActivityManagerService類的成員函數(shù)startProcessLocked為該Activity組件創(chuàng)建一個(gè)應(yīng)用程序進(jìn)程无午,然后再將其啟動(dòng)起來(lái)
  • 由于MainActivity組件是第一次自動(dòng),即這時(shí)候系統(tǒng)是不可能存在所需要的應(yīng)用程序進(jìn)程的誉券,因此指厌,接下來(lái)就會(huì)調(diào)用ActivityManagerService類的成員函數(shù)startProcessLocked來(lái)為MainActivity組件創(chuàng)建一個(gè)應(yīng)用程序進(jìn)程

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;
        //前面?zhèn)魅氲膇slated = false
        if (!isolated) {
            //檢查請(qǐng)求的進(jìn)程是否已經(jīng)存在
            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)判斷成立,所以緊接著調(diào)用getProcessRecordLocked(processName, info.uid, keepIfLarge)去檢查請(qǐng)求創(chuàng)建的進(jìn)程是否已經(jīng)存在踊跟,如果不存在緊接著調(diào)用newProcessRecordLocked(info, processName, isolated, isolatedUid);去創(chuàng)建一個(gè)ProcessRecordLocked對(duì)象踩验,這個(gè)方法中最終會(huì)將其保存在ActivityManagerService類的成員變量mProcessNames中。
  • 最后調(diào)用另外一個(gè)重載函數(shù)startProcessLocked來(lái)創(chuàng)建一個(gè)應(yīng)用進(jìn)程商玫,代碼如下:
/**
* 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{
        ...
        //獲取應(yīng)用的uid
        int uid = app.uid;
        //獲取應(yīng)用的用戶組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.
    //前面?zhèn)魅氲膃ntry==null = true
    boolean isActivityProcess = (entryPoint == null);
    //指定Process進(jìn)程的入口
    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){
        ...
    }
}
  • 上面這段代碼中首先要得到要?jiǎng)?chuàng)建的應(yīng)用進(jìn)程的用戶ID和用戶組ID箕憾,接著調(diào)用Process 類的靜態(tài)成員函數(shù)start來(lái)啟動(dòng)一個(gè)新的應(yīng)用程序進(jìn)程。
  • 新的應(yīng)用程序進(jìn)程創(chuàng)建成功之后拳昌,當(dāng)前進(jìn)程就會(huì)得到一個(gè)大于0進(jìn)程ID袭异,保存在變量startResult中。接下來(lái)將信息保存到參數(shù)app中炬藤,并且將app所指向的的一個(gè)ProcessRecord對(duì)象保存在ActivityManagerService類的成員變量mPidsSelfLocked中御铃。最后根據(jù)來(lái)向ActivityManagerService所在的線程消息對(duì)立發(fā)送一個(gè)類型為PROC_START_TIMEOUT_MSG的消息,并且startResult的成員變量usingWrapper來(lái)決定延遲時(shí)長(zhǎng)是PROC_START_TIMEOUT_WITH_WRAPPER = 12001000毫秒沈矿,還是PROC_START_TIMEOUT = 101000**毫秒上真。
  • 新的應(yīng)用程序必須在指定的時(shí)間內(nèi)完成啟動(dòng)工作苫亦,并且向ActivityManagerService發(fā)送一個(gè)啟動(dòng)完成的通知乍楚,以便ActivityManagerService可以在啟動(dòng)在該應(yīng)用程序內(nèi)部啟動(dòng)一個(gè)Acivity組件;否則ActivityManagerService就會(huì)認(rèn)為該應(yīng)用程序啟動(dòng)超時(shí)了舰涌,因此就不能將相應(yīng)的Activity組件啟動(dòng)起來(lái)
  • 前面在調(diào)用Process類的靜態(tài)成員函數(shù)start來(lái)啟動(dòng)一個(gè)新的應(yīng)用程序是陵像,指定該進(jìn)程的入口函數(shù)為android.app.ActivityThread類的靜態(tài)成員函數(shù)main就珠,因此,接下來(lái)我們就從它開始分析新的應(yīng)用程序的啟動(dòng)過程


    image.png

step24:ActivityThread.main

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

public final class ActivityThread {
    ...
    public static void main(String[] args) {
        ...
        //創(chuàng)建 消息循環(huán)
        Looper.prepareMainLooper();
        
        //創(chuàng)建ActivityThread并向ActivityManagerService發(fā)送一個(gè)啟動(dòng)完成的通知
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        ...
        //通知完成以后當(dāng)前進(jìn)程進(jìn)入消息循環(huán)的過程
        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){
                ...
            }
            ...
        }
        ...
    }   
    ...
}
  • 新的應(yīng)用進(jìn)程在啟動(dòng)時(shí)醒颖,主要做了兩件事情
    1.在進(jìn)程中創(chuàng)建一個(gè)ActivityThread對(duì)象妻怎,并且調(diào)用他的成員函數(shù)attach向ActivityManagerService發(fā)送一個(gè)啟動(dòng)完成的通知
    2.調(diào)用Lopper類的靜態(tài)成員函數(shù)prepareMainLooper創(chuàng)建一個(gè)消息循環(huán),并且在向ActivityManagerService發(fā)送啟動(dòng)完成通知之后图贸,使得當(dāng)前進(jìn)程進(jìn)入到這個(gè)消息循環(huán)中

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類的成員函數(shù)attachApplication中蹂季,首先將傳入的參數(shù)寫入到Parcel對(duì)象data中冕广,然后通過ActivityManagerProxy類內(nèi)部的一個(gè)Binder代理對(duì)象mRemote向ActivityManagerService發(fā)送一個(gè)ATTACH_APPLICATION_TRANSACTION的進(jìn)程間通信請(qǐng)求
  • 以上2個(gè)步驟都是在新的應(yīng)用程序進(jìn)程中執(zhí)行的疏日,接下來(lái)的26-29步是在ActivityManagerService中執(zhí)行的偿洁,主要用來(lái)處理新的應(yīng)用程序進(jìn)程發(fā)出的類型為ATTACH_APPLICATION_TRANSACTION的進(jìn)程間通信請(qǐng)求,如下圖:
    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類的成員函數(shù)attachApplication接收到新的應(yīng)用程序進(jìn)程發(fā)送過來(lái)的類型為ATTACH_APPLICATION_TRANSCATION的進(jìn)程間通信請(qǐng)求之后沟优,他就知道了新的應(yīng)用程序已經(jīng)啟動(dòng)完成了涕滋。因此,解析來(lái)就調(diào)用成員函數(shù)attachApplicationLocked來(lái)繼續(xù)執(zhí)行啟動(dòng)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;
        //移除進(jìn)程啟動(dòng)的消息
        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) {
                ...
            }
        }
    }   
    ...   
}
  • 參數(shù)pid指向了前面所創(chuàng)建的應(yīng)用進(jìn)程的PID挠阁。在前面的step 23中宾肺,ActivityManagerService以這個(gè)PID為關(guān)鍵字將一個(gè)ProcessRecord對(duì)象保存在了成員比那里那個(gè)mPiedsSelfLocked中。因此app = mPidsSelfLocked.get(pid)可以通過參數(shù)pid直接將這個(gè)ProcessRecord取出來(lái)侵俗,并保存到局部變量app中
  • 前面的到的ProcessRecord對(duì)象app就是用來(lái)描述新創(chuàng)建的應(yīng)用程序進(jìn)程的锨用。居然這個(gè)應(yīng)用程序進(jìn)程現(xiàn)在已經(jīng)啟動(dòng)起來(lái)了,那緊接著就可以對(duì)這個(gè)變量app進(jìn)程一些初始化的操作隘谣,其中最重要的步驟是在app.makeActive(thread, mProcessStats)中,這里面的代碼最終將app持有的成員變量thread設(shè)置參數(shù)thread所指向的一個(gè)ApplicationThread代理對(duì)象增拥,代碼簡(jiǎn)單來(lái)說(shuō)是這樣的public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {thread = _thread;};這樣ActivityManagerService就可以通過這個(gè)ApplicationThread代理對(duì)象來(lái)和新建的應(yīng)用程序進(jìn)行通信
  • 隨后調(diào)用mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);移除當(dāng)前線程的消息隊(duì)列中類型為PROC_START_TIMEOUT_MSG的消息寻歧,因?yàn)樾碌膽?yīng)用程序進(jìn)程已經(jīng)在規(guī)定的時(shí)間內(nèi)啟動(dòng)起來(lái)了
  • 接下來(lái)調(diào)用mStackSupervisor.attachApplicationLocked(app)去判斷是否有新的Activity組件要啟動(dòng)起來(lái)掌栅,跟進(jìn)查看

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;
                }
                //找到即將要啟動(dòng)的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的成員函數(shù)attacApplication首先循環(huán)便利所有維護(hù)的Activity組件堆棧,找到要啟動(dòng)的MainActivity組件的堆棧码泛,然后獲取位于棧頂?shù)囊粋€(gè)ActivityRecord對(duì)象r猾封。接著檢查這個(gè)Activity組件的用戶ID和進(jìn)程名是否于ProcessRecord對(duì)象app的所描述的應(yīng)用程序進(jìn)程的用戶ID和進(jìn)程名一致。如果一致噪珊,那么說(shuō)明ActiivtyRecord對(duì)象hr所描述的Activity組件是應(yīng)用在ProcessRecord對(duì)象app所描述的應(yīng)用程序進(jìn)程中啟動(dòng)的晌缘,因此,接下來(lái)就會(huì)調(diào)用ActivityStackSupervisor的成員函數(shù)realStartActivityLocked來(lái)請(qǐng)求改應(yīng)用程序啟動(dòng)一個(gè)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組件添加到參數(shù)app所描述的應(yīng)用程序進(jìn)程的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類的成員函數(shù)realStartActivityLocked中痢站,首先將參數(shù)r的成員變量app的值設(shè)置為參數(shù)app磷箕,表示他描述的Activity組件是在參數(shù)app所描述的應(yīng)用程序進(jìn)程中啟動(dòng)的,接下來(lái)將r所描述的Activity組件添加到參數(shù)app所描述的應(yīng)用程序進(jìn)程的Activity組件列表中
  • 完成前面的一系列準(zhǔn)備工作以后瑟押,緊接著調(diào)用參數(shù)app的成員變量thread的成員函數(shù)scheduleLaunchActivity搀捷,來(lái)通知前面創(chuàng)建的應(yīng)用程序進(jìn)程啟動(dòng)由參數(shù)r所描述的一個(gè)Activity組件,即MainActivity組件多望,接下來(lái)的調(diào)用流程圖如下


    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);
        }
        ...
    }
    ...
}
  • 可以看到這里將之前傳入的信息保存到一個(gè)ActiivtyRecordClient對(duì)象r中嫩舟,然后發(fā)送一個(gè)類型為LAUNCH_ACTIVITY的消息給ActivityThread的內(nèi)部類H進(jìn)行處理

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;
        }
    }
}
  • 可以看到將前面?zhèn)魅氲南⑦M(jìn)行解析,然后調(diào)用成員函數(shù)getPackageInfoNoCheck來(lái)獲得一個(gè)LoadedApk對(duì)象怀偷,并保存在ActivityRecord對(duì)象r的成員變量packageInfo中
  • 我們知道家厌,每一個(gè)Android應(yīng)用程序都是打包在一個(gè)Apk文件中的。一個(gè)Apk文件包含了一個(gè)Android應(yīng)用程序的所有資源椎工,應(yīng)用程序進(jìn)程在doing一個(gè)Activity組件時(shí)饭于,需要將它的Apk文件加載進(jìn)來(lái)蜀踏,以便可以訪問它里面的資源。在ActivityThread類內(nèi)部掰吕,就是用一個(gè)Loaded對(duì)象來(lái)描述一個(gè)已經(jīng)加載的Apk文件
  • 最后調(diào)用ActivityThread類的成員函數(shù)handleLaunchActivity來(lái)啟動(dòng)由ActiivtyClientRecord對(duì)象r所描述的一個(gè)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;
            //后續(xù)會(huì)引起一些列的onResume相關(guān)的生命周期相關(guān)的操作
            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類的成員函數(shù)handlLaunchActivity中首先調(diào)用成員函數(shù)performLaunchActivity將MainActivity啟動(dòng)起來(lái)殖熟,接著調(diào)用成員函數(shù)handleResumeActivity將MainActivity組件的狀態(tài)置為Resumed局待,表示它是系統(tǒng)當(dāng)前激活的Activity組件。
  • 記下來(lái)菱属,我們就主要關(guān)注MainActiivty組件的啟動(dòng)過程钳榨,即ActivityThread的成員函數(shù)performLaunchActivity的實(shí)現(xiàn)

step 32:ActivityThread.performLaunchActivity

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

final class ActivityThead{
    ...
    private Activity performLaunchActivity(ActivityClientRecord r, 
        Intent customIntent){
        
        ...
        //獲取要啟動(dòng)的MainActivity信息
        ComponentName component = r.intent.getComponent();
        ...
        //加載要啟動(dòng)的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) {
                //創(chuàng)建上下文運(yùn)行環(huán)境
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = 
                    r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                ...
                //基礎(chǔ)信息的保存
                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類的成員函數(shù)perforeLaunchActivity手電調(diào)用ComponentName component = r.intent.getComponent();獲取要啟動(dòng)的Activity組件的包名及類名,存儲(chǔ)到變量component中纽门。接著將他的淚文件加載到內(nèi)存中薛耻,并創(chuàng)建一個(gè)實(shí)例。由于所有的Activity組件都是從Activity類繼承下來(lái)的赏陵,我們就可以將前面創(chuàng)建的Activity組件保存在Activity對(duì)象activity中
  • 接下創(chuàng)建和初始化了一個(gè)ContextImpl對(duì)象appContext饼齿,用來(lái)作為前面所處創(chuàng)建的Activity對(duì)象activity的運(yùn)行上下文環(huán)境,通過它就可以訪問到特定的應(yīng)用程序資源瘟滨,以及啟動(dòng)其他的應(yīng)用程序組件候醒。接著使用ContextImpl對(duì)象appContext和ActivityClientRecord對(duì)象r來(lái)初始化Activity對(duì)象activity
  • Activity對(duì)象初始化完成之后,緊接著調(diào)用成員函數(shù)mInstrumentation的成員函數(shù)callActivityOnCreate將Activity對(duì)象啟動(dòng)起來(lái)杂瘸。在這個(gè)過程中倒淫,Activity對(duì)象actiivty的成員函數(shù)onCreate就會(huì)被調(diào)用。一般來(lái)說(shuō)败玉,我們?cè)谧远x一個(gè)Activity組件時(shí)敌土,都會(huì)重寫其父類Activity的成員函數(shù)onCreate,以便可以加載自己的用戶界面运翼,以及執(zhí)行其他的一些業(yè)務(wù)相關(guān)的初始化操作
  • Activity對(duì)象activity啟動(dòng)完成之后返干,緊接著就會(huì)以ActivityClientRecord對(duì)象r的成員變量token為關(guān)鍵字,將ActivityRecordClient對(duì)象r保存在ActivityThread類的成員變量mActivities中
  • 接下來(lái)就是我們經(jīng)逞剩看到的MainActivity的onCreate調(diào)用執(zhí)行矩欠。至此MainActivity組件的啟動(dòng)流程就分析完畢了。MainActivity組件作為應(yīng)用程序的入口悠夯,它啟動(dòng)起來(lái)就意味著整個(gè)應(yīng)用程序便啟動(dòng)起來(lái)了癌淮。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市沦补,隨后出現(xiàn)的幾起案子乳蓄,更是在濱河造成了極大的恐慌,老刑警劉巖夕膀,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虚倒,死亡現(xiàn)場(chǎng)離奇詭異美侦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)魂奥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門菠剩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人捧弃,你說(shuō)我怎么就攤上這事赠叼〔聊遥” “怎么了违霞?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瞬场。 經(jīng)常有香客問我买鸽,道長(zhǎng),這世上最難降的妖魔是什么贯被? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任眼五,我火速辦了婚禮,結(jié)果婚禮上彤灶,老公的妹妹穿的比我還像新娘看幼。我一直安慰自己,他們只是感情好幌陕,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布诵姜。 她就那樣靜靜地躺著,像睡著了一般搏熄。 火紅的嫁衣襯著肌膚如雪棚唆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天心例,我揣著相機(jī)與錄音宵凌,去河邊找鬼。 笑死止后,一個(gè)胖子當(dāng)著我的面吹牛瞎惫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播译株,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼瓜喇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了古戴?” 一聲冷哼從身側(cè)響起欠橘,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎现恼,沒想到半個(gè)月后肃续,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體黍檩,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年始锚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了刽酱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瞧捌,死狀恐怖棵里,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情姐呐,我是刑警寧澤殿怜,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站曙砂,受9級(jí)特大地震影響头谜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鸠澈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一柱告、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笑陈,春花似錦际度、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至妹笆,卻和暖如春块请,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拳缠。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工墩新, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窟坐。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓海渊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親哲鸳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子臣疑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容