Activity啟動(dòng)流程詳解(基于api28)

建議讀者前往我的個(gè)人博客閱讀。更精美的ui擁有更好的閱讀體驗(yàn)
點(diǎn)擊前往我的個(gè)人博客

前言

Activity作為Android四大組件之一,他的啟動(dòng)絕對(duì)沒(méi)有那么簡(jiǎn)單进陡。這里涉及到了系統(tǒng)服務(wù)進(jìn)程橙凳,啟動(dòng)過(guò)程細(xì)節(jié)很多窟绷,這里我只展示主體流程脖咐。activity的啟動(dòng)流程隨著版本的更替瓜浸,代碼細(xì)節(jié)一直在進(jìn)行更改,每次都會(huì)有很大的修改秋冰,如android5.0 android8.0仲义。我這里的版本是基于android api28,也是目前我可以查得到的最新源碼了剑勾。事實(shí)上大題的流程是相同的埃撵,掌握了一個(gè)版本,其他的版本通過(guò)源碼也可以很快地掌握虽另。

因?yàn)樯婕暗讲煌倪M(jìn)程之間的通信:系統(tǒng)服務(wù)進(jìn)程和本地進(jìn)程暂刘,在最新版本的android使用的是AIDL來(lái)跨進(jìn)程通信。所以需要對(duì)AIDL有一定的了解捂刺,會(huì)幫助理解整個(gè)啟動(dòng)流程谣拣。

源碼部分的講解涉及到很多的代碼講解,可能會(huì)有一點(diǎn)不適族展,但還是建議看完源碼森缠。源碼的關(guān)鍵代碼處我都會(huì)加上注釋,方便理解仪缸。

代碼不會(huì)過(guò)分關(guān)注細(xì)節(jié)贵涵,只注重整體流程。想知道具體細(xì)節(jié)可以去查看源碼恰画。每份代碼所在的路徑我都會(huì)在代碼前面標(biāo)注出來(lái)宾茂,各位可以去查看相對(duì)應(yīng)的源碼。

每部分源碼前我都會(huì)放流程圖锣尉,一定要配合流程圖食用刻炒,不然可能會(huì)亂。

整體流程概述

這一部分側(cè)重于對(duì)整個(gè)啟動(dòng)流程的概述自沧,在心中有大體的概念坟奥,這樣可以幫助對(duì)下面具體細(xì)節(jié)流程的理解。

普通Activity的創(chuàng)建

普通Activity創(chuàng)建也就是平常我們?cè)诖a中采用startActivity(Intent intent)方法來(lái)創(chuàng)建Activity的方式拇厢“總體流程如下圖:

image

啟動(dòng)過(guò)程設(shè)計(jì)到兩個(gè)進(jìn)程:本地進(jìn)程和系統(tǒng)服務(wù)進(jìn)程。本地進(jìn)程也就是我們的應(yīng)用所在進(jìn)程孝偎,系統(tǒng)服務(wù)進(jìn)程為所有應(yīng)用共用的服務(wù)進(jìn)程访敌。整體思路是:

  1. activity向Instrumentation請(qǐng)求創(chuàng)建

  2. Instrumentation通過(guò)AMS在本地進(jìn)程的IBinder接口,訪問(wèn)AMS衣盾,這里采用的跨進(jìn)程技術(shù)是AIDL寺旺。

  3. 然后AMS進(jìn)程一系列的工作爷抓,如判斷該activity是否存在,啟動(dòng)模式是什么阻塑,有沒(méi)有進(jìn)行注冊(cè)等等蓝撇。

  4. 通過(guò)ClientLifeCycleManager,利用本地進(jìn)程在系統(tǒng)服務(wù)進(jìn)程的IBinder接口直接訪問(wèn)本地ActivityThread陈莽。

    ApplicationThread是ActivityThread的內(nèi)部類渤昌,IApplicationThread是在遠(yuǎn)程服務(wù)端的Binder接口

  5. ApplicationThread接收到服務(wù)端的事務(wù)后,把事務(wù)直接轉(zhuǎn)交給ActivityThread處理走搁。

  6. ActivityThread通過(guò)Instrumentation利用類加載器進(jìn)行創(chuàng)建實(shí)例独柑,同時(shí)利用Instrumentation回調(diào)activity的生命中周期

這里涉及到了兩個(gè)進(jìn)程,本地進(jìn)程主要負(fù)責(zé)創(chuàng)建activity以及回調(diào)生命周期私植,服務(wù)進(jìn)程主要判斷該activity是否合法忌栅,是否需要?jiǎng)?chuàng)建activity棧等等。進(jìn)程之間就涉及到了進(jìn)程通信:AIDL兵琳。(如果不熟悉可以先去了解一下狂秘,但可以簡(jiǎn)單理解為接口回調(diào)即可)

下面介紹幾個(gè)關(guān)鍵類:

  • Instrumentation是activity與外界聯(lián)系的類(不是activity本身的統(tǒng)稱外界骇径,相對(duì)activity而言)躯肌,activity通過(guò)Instrumentation來(lái)請(qǐng)求創(chuàng)建,ActivityThread通過(guò)Instrumentation來(lái)創(chuàng)建activity和調(diào)用activity的生命周期破衔。

  • ActivityThread清女,每個(gè)應(yīng)用程序唯一一個(gè)實(shí)例,負(fù)責(zé)對(duì)Activity創(chuàng)建的管理晰筛,而ApplicationThread只是應(yīng)用程序和服務(wù)端進(jìn)程通信的類而已嫡丙,只負(fù)責(zé)通信,把AMS的任務(wù)交給ActivityThread读第。

  • AMS曙博,全稱ActivityManagerService,負(fù)責(zé)統(tǒng)籌服務(wù)端對(duì)activity創(chuàng)建的流程怜瞒。

    其他的類父泳,后面的源碼解析會(huì)詳解。

根Activity的創(chuàng)建

根Activity也就是我們點(diǎn)擊桌面圖標(biāo)的時(shí)候吴汪,應(yīng)用程序第一個(gè)activity啟動(dòng)的流程惠窄。這里我側(cè)重講解多個(gè)進(jìn)程之間的關(guān)系,下面的源碼也不會(huì)講細(xì)節(jié)漾橙,只講解普通activity的創(chuàng)建流程杆融。這里也相當(dāng)于一個(gè)補(bǔ)充。先看整體流程圖:

image

主要涉及四個(gè)進(jìn)程:

  • Launcher進(jìn)程霜运,也就是桌面進(jìn)程
  • 系統(tǒng)服務(wù)進(jìn)程脾歇,AMS所在進(jìn)程
  • Zygote進(jìn)程蒋腮,負(fù)責(zé)創(chuàng)建進(jìn)程
  • 應(yīng)用程序進(jìn)程,也就是即將要啟動(dòng)的進(jìn)程

主要流程:

  1. Launcher進(jìn)程請(qǐng)求AMS創(chuàng)建activity
  2. AMS請(qǐng)求Zygote創(chuàng)建進(jìn)程藕各。
  3. Zygote通過(guò)fork自己來(lái)創(chuàng)建進(jìn)程徽惋。并通知AMS創(chuàng)建完成。
  4. AMS通知應(yīng)用進(jìn)程創(chuàng)建根Activity座韵。

和普通Activity的創(chuàng)建很像险绘,主要多了創(chuàng)建進(jìn)程這一步。

源碼講解

Activity請(qǐng)求AMS的過(guò)程

流程圖
image
源碼
  1. 系統(tǒng)通過(guò)調(diào)用Launcher的startActivitySafely方法來(lái)啟動(dòng)應(yīng)用程序誉碴。Launcher是一個(gè)類宦棺,負(fù)責(zé)啟動(dòng)根Activity。

    這一步是根Activity啟動(dòng)才有的流程黔帕,普通啟動(dòng)是沒(méi)有的代咸,放在這里是作為一點(diǎn)補(bǔ)充而已

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java/;
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
     //這里調(diào)用了父類的方法,繼續(xù)查看父類的方法實(shí)現(xiàn)
        boolean success = super.startActivitySafely(v, intent, item);
        ...
        return success;
    }
    
packages/apps/Launcher3/src/com/android/launcher3/BaseDraggingActivity.java/;
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
        ...
        // Prepare intent
        //設(shè)置標(biāo)志singleTask成黄,意味著在新的棧打開(kāi)
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (v != null) {
            intent.setSourceBounds(getViewBounds(v));
        }
        try {
            boolean isShortcut = Utilities.ATLEAST_MARSHMALLOW
                    && (item instanceof ShortcutInfo)
                    && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                    || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                    && !((ShortcutInfo) item).isPromise();
            //下面注釋1和注釋2都是直接采用startActivity進(jìn)行啟動(dòng)呐芥。注釋1會(huì)做一些設(shè)置
            //BaseDraggingActivity是繼承自BaseActivity,而B(niǎo)aseActivity是繼承自Activity
            //所以直接就跳轉(zhuǎn)到了Activity的startActivity邏輯奋岁。
            if (isShortcut) {
                // Shortcuts need some special checks due to legacy reasons.
                startShortcutIntentSafely(intent, optsBundle, item);//1
            } else if (user == null || user.equals(Process.myUserHandle())) {
                // Could be launching some bookkeeping activity
                startActivity(intent, optsBundle);//2
            } else {
                LauncherAppsCompat.getInstance(this).startActivityForProfile(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
            }
            
           ...
        } 
     ...
        return false;
    }
  1. Activity通過(guò)Instrumentation來(lái)啟動(dòng)Activity

    /frameworks/base/core/java/android/app/Activity.java/;
    public void startActivity(Intent intent, @Nullable Bundle options) {
         //最終都會(huì)跳轉(zhuǎn)到startActivityForResult這個(gè)方法
            if (options != null) {
                startActivityForResult(intent, -1, options);
            } else {
                // Note we want to go through this call for compatibility with
                // applications that may have overridden the method.
                startActivityForResult(intent, -1);
            }
        }
    
    public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
                @Nullable Bundle options) {
         //mParent是指activityGroup思瘟,現(xiàn)在已經(jīng)采用Fragment代替,這里會(huì)一直是null
         //下一步會(huì)通過(guò)mInstrumentation.execStartActivity進(jìn)行啟動(dòng)
            if (mParent == null) {
                options = transferSpringboardActivityOptions(options);
                Instrumentation.ActivityResult ar =
                    mInstrumentation.execStartActivity(
                        this, mMainThread.getApplicationThread(), mToken, this,
                        intent, requestCode, options);//1
                if (ar != null) {
                    mMainThread.sendActivityResult(
                        mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                        ar.getResultData());
                }
                ...
            }
        ...
    }
    
  2. Instrumentation請(qǐng)求AMS進(jìn)行啟動(dòng)闻伶。該類的作用是監(jiān)控應(yīng)用程序和系統(tǒng)的交互滨攻。到此為止,任務(wù)就交給了AMS了蓝翰,AMS進(jìn)行一系列處理后光绕,會(huì)通過(guò)本地的接口IActivityManager來(lái)進(jìn)行回調(diào)啟動(dòng)activity。

    /frameworks/base/core/java/android/app/Instrumentation.java/;
    public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
        ...
        //這個(gè)地方比較復(fù)雜畜份,先說(shuō)結(jié)論诞帐。下面再進(jìn)行解釋    
        //ActivityManager.getService()獲取到的對(duì)象是ActivityManagerService,簡(jiǎn)稱AMS
        //通過(guò)AMS來(lái)啟動(dòng)activity爆雹。AMS是全局唯一的停蕉,所有的活動(dòng)啟動(dòng)都要經(jīng)過(guò)他的驗(yàn)證,運(yùn)行在獨(dú)立的進(jìn)程中
        //所以這里是采用AIDL的方式進(jìn)行跨進(jìn)程通信顶别,獲取到的對(duì)象其實(shí)是一個(gè)IBinder接口
            
        //注釋2是進(jìn)行檢查啟動(dòng)結(jié)果谷徙,如果異常則拋出,如沒(méi)有注冊(cè)驯绎。
        try {
                intent.migrateExtraStreamToClipData();
                intent.prepareToLeaveProcess(who);
                int result = ActivityManager.getService()
                    .startActivity(whoThread, who.getBasePackageName(), intent,
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            token, target != null ? target.mEmbeddedID : null,
                            requestCode, 0, null, options);//1
                checkStartActivityResult(result, intent);//2
            } catch (RemoteException e) {
                throw new RuntimeException("Failure from system", e);
            }
            return null;
        
    }
    

    這一步是通過(guò)AIDL技術(shù)進(jìn)行跨進(jìn)行通信完慧。拿到AMS的代理對(duì)象,把啟動(dòng)任務(wù)交給了AMS剩失。

    /frameworks/base/core/java/android/app/ActivityManager.java/;
    //單例類
    public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
    }
    
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
    new Singleton<IActivityManager>() {
    @Override
    protected IActivityManager create() {
    //得到AMS的IBinder接口
    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
    //轉(zhuǎn)化成IActivityManager對(duì)象屈尼。遠(yuǎn)程服務(wù)實(shí)現(xiàn)了這個(gè)接口册着,所以可以直接調(diào)用這個(gè)
    //AMS代理對(duì)象的接口方法來(lái)請(qǐng)求AMS。這里采用的技術(shù)是AIDL
    final IActivityManager am = IActivityManager.Stub.asInterface(b);
    return am;
    }
    };
    

AMS處理請(qǐng)求的過(guò)程

流程圖
image
源碼
  1. 接下來(lái)看AMS的實(shí)現(xiàn)邏輯脾歧。AMS這部分的源碼是通過(guò)ActivityStartController來(lái)創(chuàng)建一個(gè)ActivityStarter甲捏,然后把邏輯都交給ActivityStarter去執(zhí)行。ActivityStarter是android 7.0加入的類鞭执。

     /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java/;
    //跳轉(zhuǎn)到startActivityAsUser
    //注意最后多了一個(gè)參數(shù)UserHandle.getCallingUserId()司顿,表示調(diào)用者權(quán)限
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
    }
    
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
                Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
                int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
                boolean validateIncomingUser) {
            enforceNotIsolatedCaller("startActivity");
    
            userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
                    Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
    
            // TODO: Switch to user app stacks here.
         //這里通過(guò)ActivityStartController獲取到ActivityStarter,通過(guò)ActivityStarter來(lái)
         //執(zhí)行啟動(dòng)任務(wù)兄纺。這里就把任務(wù)邏輯給到了AcitivityStarter
            return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
                    .setCaller(caller)
                    .setCallingPackage(callingPackage)
                    .setResolvedType(resolvedType)
                    .setResultTo(resultTo)
                    .setResultWho(resultWho)
                    .setRequestCode(requestCode)
                    .setStartFlags(startFlags)
                    .setProfilerInfo(profilerInfo)
                    .setActivityOptions(bOptions)
                    .setMayWait(userId)
                    .execute();
    
        }
    

    ActivityStartController獲取ActivityStarter

    /frameworks/base/services/core/java/com/android/server/am/ActivityStartController.java/;
    //獲取到ActivityStarter對(duì)象大溜。這個(gè)對(duì)象僅使用一次,當(dāng)他的execute被執(zhí)行后估脆,該對(duì)象作廢
    ActivityStarter obtainStarter(Intent intent, String reason) {
    return mFactory.obtain().setIntent(intent).setReason(reason);
    }
    
  2. 這部分主要是ActivityStarter的源碼內(nèi)容钦奋,涉及到的源碼非常多。AMS把整個(gè)啟動(dòng)邏輯都丟給ActivityStarter去處理了疙赠。這里主要做啟動(dòng)前處理付材,創(chuàng)建進(jìn)程等等。

    /frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java/;
    //這里需要做啟動(dòng)預(yù)處理圃阳,執(zhí)行startActivityMayWait方法
    int execute() {
            try {
                 ...
                if (mRequest.mayWait) {
                    return startActivityMayWait(mRequest.caller, mRequest.callingUid,
                            mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
                            mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
                            mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
                            mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
                            mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
                            mRequest.inTask, mRequest.reason,
                            mRequest.allowPendingRemoteAnimationRegistryLookup);
                }
                ...
            } 
         ...
        }
    
    //啟動(dòng)預(yù)處理
    private 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 globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
                int userId, TaskRecord inTask, String reason,
                boolean allowPendingRemoteAnimationRegistryLookup) {
            ...
         //跳轉(zhuǎn)startActivity
             final ActivityRecord[] outRecord = new ActivityRecord[1];
             int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                    ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                    allowPendingRemoteAnimationRegistryLookup);
    }
    
    //記錄啟動(dòng)進(jìn)程和activity的信息
    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            SafeActivityOptions options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
        ...
        //得到Launcher進(jìn)程    
        ProcessRecord callerApp = null;
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            ...
        }
        ...
        //記錄得到的activity信息
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, checkedOptions, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }
        ...
        mController.doPendingActivityLaunches(false);
     //繼續(xù)跳轉(zhuǎn)
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
                true /* doResume */, checkedOptions, inTask, outActivity);
    }
    
    //跳轉(zhuǎn)startActivityUnchecked
    private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
        int result = START_CANCELED;
        try {
            mService.mWindowManager.deferSurfaceLayout();
            //跳轉(zhuǎn)
            result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, outActivity);
        } 
        ...
        return result;
    }
    
    //主要做與棧相關(guān)的邏輯處理厌衔,并跳轉(zhuǎn)到ActivityStackSupervisor進(jìn)行處理
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        ...
        int result = START_SUCCESS;
        //這里和我們最初在Launcher設(shè)置的標(biāo)志FLAG_ACTIVITY_NEW_TASK相關(guān),會(huì)創(chuàng)建一個(gè)新棧
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
        }
        ...
        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                ...
            } else {
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                //跳轉(zhuǎn)到ActivityStackSupervisor進(jìn)行處理
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                                                                mOptions);
            }
        }
    }
    
  3. ActivityStackSupervisor主要負(fù)責(zé)做activity棧的相關(guān)工作限佩,會(huì)結(jié)合ActivityStack來(lái)進(jìn)行工作葵诈。主要判斷activity的狀態(tài),是否處于棧頂或處于停止?fàn)顟B(tài)等

    /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java/;
    
    boolean resumeFocusedStackTopActivityLocked(
            ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
     ...
        //判斷要啟動(dòng)的activity是不是出于停止?fàn)顟B(tài)或者Resume狀態(tài)
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        if (r == null || !r.isState(RESUMED)) {
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.isState(RESUMED)) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }
    
  4. ActivityStack主要處理activity在棧中的狀態(tài)

    /frameworks/base/services/core/java/com/android/server/am/ActivityStack.java/;
    //跳轉(zhuǎn)resumeTopActivityInnerLocked
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }
        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            //跳轉(zhuǎn)resumeTopActivityInnerLocked
            result = resumeTopActivityInnerLocked(prev, options);
     ...
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }
    
    //跳轉(zhuǎn)到StackSupervisor.startSpecificActivityLocked祟同,注釋1
    @GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ...
        if (next.app != null && next.app.thread != null) {
            ...
        } else {
            ...
            mStackSupervisor.startSpecificActivityLocked(next, true, true);//1
        }     
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }
    
  5. 這里又回到了ActivityStackSupervisor,判斷進(jìn)程是否已經(jīng)創(chuàng)建理疙,未創(chuàng)建拋出異常晕城。然后創(chuàng)建事務(wù)交回給本地執(zhí)行。這里的事務(wù)很關(guān)鍵窖贤,Activity執(zhí)行的工作就是這個(gè)事務(wù)砖顷,事務(wù)的內(nèi)容是里面的item,所以要注意下面的兩個(gè)item赃梧。

    /frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java/;
    
    void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        //得到即將啟動(dòng)的activity所在的進(jìn)程
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);
        getLaunchTimeTracker().setLaunchTime(r);
    
        //判斷該進(jìn)程是否已經(jīng)啟動(dòng),跳轉(zhuǎn)realStartActivityLocked滤蝠,真正啟動(dòng)活動(dòng)
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);//1
                return;
            } 
            ...
        }
        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }
    
    
    //主要?jiǎng)?chuàng)建事務(wù)交給本地執(zhí)行
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
        ...
        //創(chuàng)建啟動(dòng)activity的事務(wù)ClientTransaction對(duì)象
        // Create activity launch transaction.
        final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                r.appToken);
        // 添加LaunchActivityItem,該item的內(nèi)容是創(chuàng)建activity
        clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                System.identityHashCode(r), r.info,
                // TODO: Have this take the merged configuration instead of separate global
                // and override configs.
                mergedConfiguration.getGlobalConfiguration(),
                mergedConfiguration.getOverrideConfiguration(), r.compat,
                r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                profilerInfo));
    
        // Set desired final state.
        //添加執(zhí)行Resume事務(wù)ResumeActivityItem,后續(xù)會(huì)在本地被執(zhí)行
        final ActivityLifecycleItem lifecycleItem;
        if (andResume) {
            lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
        } else {
            lifecycleItem = PauseActivityItem.obtain();
        }
        clientTransaction.setLifecycleStateRequest(lifecycleItem);
    
        // 通過(guò)ClientLifecycleManager來(lái)啟動(dòng)事務(wù)
        // 這里的mService就是AMS
        // 記住上面兩個(gè)item:LaunchActivityItem和ResumeActivityItem授嘀,這是事務(wù)的執(zhí)行單位
        // Schedule transaction.
        mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    }
        
    

    通過(guò)AMS獲取ClientLifecycleManager

    /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java/;
    //通過(guò)AMS獲取ClientLifecycleManager
    ClientLifecycleManager getLifecycleManager() {
    return mLifecycleManager;
    }
    
  6. ClientLifecycleManager是事務(wù)管理類物咳,負(fù)責(zé)執(zhí)行事務(wù)

    /frameworks/base/services/core/java/com/android/server/am/ClientLifecycleManager.java
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        //執(zhí)行事務(wù)
        transaction.schedule();
        if (!(client instanceof Binder)) {
            transaction.recycle();
        }
    }
    
  7. 把事務(wù)交給本地ActivityThread執(zhí)行。這里通過(guò)本地ApplicationThread在服務(wù)端的接口IApplicationThread來(lái)進(jìn)行跨進(jìn)程通信蹄皱。后面的邏輯就回到了應(yīng)用程序進(jìn)程了览闰。

    /frameworks/base/core/java/android/app/servertransaction/ClientTransaction.java/;
    
    //這里的IApplicationThread是要啟動(dòng)進(jìn)程的IBinder接口
    //ApplicationThread是ActivityThread的內(nèi)部類芯肤,IApplicationThread是IBinder代理接口
    //這里將邏輯轉(zhuǎn)到本地來(lái)執(zhí)行
    private IApplicationThread mClient;
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }
    

ActivityThread創(chuàng)建Activity的過(guò)程

流程圖
image
源碼
  1. IApplicationThread接口的本地實(shí)現(xiàn)類ActivityThread的內(nèi)部類ApplicationThread

    /frameworks/base/core/java/android/app/ActivityThread.java/ApplicationThread.class/;
    //跳轉(zhuǎn)到ActivityThread的方法實(shí)現(xiàn)
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }
    
  2. ActivityThread執(zhí)行事務(wù)。ActivityThread是繼承ClientTransactionHandler压鉴,scheduleTransaction的具體實(shí)現(xiàn)是在ClientTransactionHandler實(shí)現(xiàn)的崖咨。這里的主要內(nèi)容是把事務(wù)發(fā)送給ActivityThread的內(nèi)部類H去執(zhí)行。H是一個(gè)Handle油吭,通過(guò)這個(gè)Handle來(lái)切到主線程執(zhí)行邏輯击蹲。

    /frameworks/base/core/java/android/app/ClientTransactionHandler.java
    void scheduleTransaction(ClientTransaction transaction) {
        //事務(wù)預(yù)處理
        transaction.preExecute(this);
        //這里很明顯可以利用Handle機(jī)制切換線程,下面看看這個(gè)方法的實(shí)現(xiàn)
        //該方法的具體實(shí)現(xiàn)是在ActivityThread婉宰,是ClientTransactionHandler的抽象方法
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    
    /frameworks/base/core/java/android/app/ActivityThread.java/;
    final H mH = new H();
    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        //利用Handle進(jìn)行切換际邻。mH是H這個(gè)類的實(shí)例
        mH.sendMessage(msg);
    }
    
    
  3. H對(duì)事務(wù)進(jìn)行處理。調(diào)用事務(wù)池來(lái)處理事務(wù)

    /frameworks/base/core/java/android/app/ActivityThread.java/H.class
    //調(diào)用事務(wù)池對(duì)事務(wù)進(jìn)行處理
    public void handleMessage(Message msg) {
        if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
        switch (msg.what) {
            ...
            case EXECUTE_TRANSACTION:
                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                //調(diào)用事務(wù)池對(duì)事務(wù)進(jìn)行處理
                mTransactionExecutor.execute(transaction);
                if (isSystem()) {
                    transaction.recycle();
                }
                // TODO(lifecycler): Recycle locally scheduled transactions.
                break;
                ...
        }
        ...
    }
    
  4. 事務(wù)池對(duì)事務(wù)進(jìn)行處理芍阎。事務(wù)池會(huì)把事務(wù)中的兩個(gè)item拿出來(lái)分別執(zhí)行世曾。這兩個(gè)事務(wù)就是上面我講的兩個(gè)Item。對(duì)應(yīng)不同的初始化工作谴咸。

    /frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java
        
    public void execute(ClientTransaction transaction) {
        final IBinder token = transaction.getActivityToken();
        log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);
    
        //執(zhí)行事務(wù)
        //這兩個(gè)事務(wù)就是當(dāng)時(shí)在ActivityStackSupervisor中添加的兩個(gè)事件(第8步)
        //注釋1執(zhí)行activity的創(chuàng)建轮听,注釋2執(zhí)行activity的窗口等等并調(diào)用onStart和onResume方法
        //后面主要深入注釋1的流程
        executeCallbacks(transaction);//1
        executeLifecycleState(transaction);//2
        mPendingActions.clear();
        log("End resolving transaction");
    }
    
    public void executeCallbacks(ClientTransaction transaction) {
        ...
            //執(zhí)行事務(wù)
            //這里的item就是當(dāng)初添加的Item,還記得是哪個(gè)嗎岭佳?
             // 對(duì)了就是LaunchActivityItem
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
        ...
    }
    
    private void executeLifecycleState(ClientTransaction transaction) {
        ...
        // 和上面的一樣血巍,執(zhí)行事務(wù)中的item,item類型是ResumeActivityItem
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
    
    
  5. LaunchActivityItem調(diào)用ActivityThread執(zhí)行創(chuàng)建邏輯珊随。

    /frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java/;
    
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mIsForward,
                mProfilerInfo, client);
        // ClientTransactionHandler是ActivityThread實(shí)現(xiàn)的接口述寡,具體邏輯回到ActivityThread
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    
  6. ActivityThread執(zhí)行Activity的創(chuàng)建。主要利用Instrumentation來(lái)創(chuàng)建activity和回調(diào)activity的生命周期叶洞,并創(chuàng)建activity的上下文和app上下文(如果還沒(méi)創(chuàng)建的話)鲫凶。

    /frameworks/base/core/java/android/app/ActivityThread.java/;
    
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        ...
            // 跳轉(zhuǎn)到performLaunchActivity
            final Activity a = performLaunchActivity(r, customIntent);
        ...
    }
    
    //使用Instrumentation去創(chuàng)建activity回調(diào)生命周期
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
         //獲取ActivityInfo,用戶存儲(chǔ)代碼衩辟、AndroidManifes信息螟炫。
         ActivityInfo aInfo = r.activityInfo;
            if (r.packageInfo == null) {
                //獲取apk描述類
                r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                        Context.CONTEXT_INCLUDE_CODE);
            }
        
         // 獲取activity的包名類型信息
         ComponentName component = r.intent.getComponent();
            if (component == null) {
                component = r.intent.resolveActivity(
                    mInitialApplication.getPackageManager());
                r.intent.setComponent(component);
            }
        ...
            // 創(chuàng)建context上下文
            ContextImpl appContext = createBaseContextForActivity(r);
             // 創(chuàng)建activity
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();
                // 通過(guò)Instrumentation來(lái)創(chuàng)建活動(dòng)
                activity = mInstrumentation.newActivity(
                        cl, component.getClassName(), r.intent);
                StrictMode.incrementExpectedActivityCount(activity.getClass());
                r.intent.setExtrasClassLoader(cl);
                r.intent.prepareToEnterProcess();
                if (r.state != null) {
                    r.state.setClassLoader(cl);
                }
            }
        ...
            try {
                // 根據(jù)包名創(chuàng)建Application,如果已經(jīng)創(chuàng)建則不會(huì)重復(fù)創(chuàng)建
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                ...
                // 為Activity添加window
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }
                appContext.setOuterContext(activity);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
                }
     ...
            // 通過(guò)Instrumentation回調(diào)Activity的onCreate方法
            ctivity.mCalled = false;
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
    }    
    

    這里深入來(lái)看一下onCreate什么時(shí)候被調(diào)用

    /frameworks/base/core/java/android/app/Instrumentation.java/;
    public void callActivityOnCreate(Activity activity, Bundle icicle,
           PersistableBundle persistentState) {
       prePerformCreate(activity);
       // 調(diào)用了activity的performCreate方法
       activity.performCreate(icicle, persistentState);
       postPerformCreate(activity);
    }
    
    /frameworks/base/core/java/android/app/Activity.java/;
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
       mCanEnterPictureInPicture = true;
       restoreHasCurrentPermissionRequest(icicle);
       // 這里就回調(diào)了onCreate方法了
       if (persistentState != null) {
           onCreate(icicle, persistentState);
       } else {
           onCreate(icicle);
       }
       ...
    }
    
  7. Instrumentation通過(guò)類加載器來(lái)創(chuàng)建activity實(shí)例

    /frameworks/base/core/java/android/app/Instrumentation.java/;
    
    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        String pkg = intent != null && intent.getComponent() != null
                ? intent.getComponent().getPackageName() : null;
        // 利用AppComponentFactory進(jìn)行實(shí)例化
        return getFactory(pkg).instantiateActivity(cl, className, intent);
    }
    
  8. 最后一步艺晴,通過(guò)AppComponentFactory工廠來(lái)創(chuàng)建實(shí)例昼钻。

    /frameworks/support/compat/src/main/java/androidx/core/app/AppComponentFactory.java
    //其實(shí)就相當(dāng)于直接返回instantiateActivityCompat
    public final Activity instantiateActivity(ClassLoader cl, String className, Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return checkCompatWrapper(instantiateActivityCompat(cl, className, intent));
    }
        
    //泛型方法
    static <T> T checkCompatWrapper(T obj) {
            if (obj instanceof CompatWrapped) {
                T wrapper = (T) ((CompatWrapped) obj).getWrapper();
                if (wrapper != null) {
                    return wrapper;
                }
            }
            return obj;
        }  
    //終于到了盡頭了。利用類加載器來(lái)進(jìn)行實(shí)例化封寞。到此activity的啟動(dòng)就告一段落了然评。
    public @NonNull Activity instantiateActivityCompat(@NonNull ClassLoader cl,
            @NonNull String className, @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        try {
            return (Activity) cl.loadClass(className).getDeclaredConstructor().newInstance();
        } catch (InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException("Couldn't call constructor", e);
        }
    }
    

小結(jié)

上文通過(guò)整體流程和代碼詳解解析了一個(gè)activity啟動(dòng)時(shí)的整體流程。不知道讀者們會(huì)不會(huì)有個(gè)疑問(wèn):了解這些有什么用呢狈究?日常又用不到碗淌。當(dāng)走完這整個(gè)流程的時(shí)候,你會(huì)發(fā)現(xiàn)你對(duì)于android又深入了解了很多了,面對(duì)開(kāi)發(fā)的時(shí)候贯莺,內(nèi)心也會(huì)更加有自信心风喇,出現(xiàn)的一些bug,可能別人要解決好久缕探,而你魂莫,很快就可以解決。另外爹耗,這一部分內(nèi)容在插件化也有很大的使用耙考,也是學(xué)習(xí)插件化必學(xué)的知識(shí)。

好了講了這么多潭兽,希望以上對(duì)你有幫助倦始。有疑問(wèn)可以評(píng)論區(qū)或者私信交流一下。另外山卦,博主屬于android新手鞋邑,如有不對(duì)之處還望指正。

參考文獻(xiàn)

最后編輯于
?著作權(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)離奇詭異箱玷,居然都是意外死亡怨规,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門锡足,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)波丰,“玉大人,你說(shuō)我怎么就攤上這事舱污⊙教颍” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵扩灯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我霜瘪,道長(zhǎng)珠插,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任颖对,我火速辦了婚禮捻撑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己顾患,他們只是感情好番捂,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著江解,像睡著了一般设预。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上犁河,一...
    開(kāi)封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天鳖枕,我揣著相機(jī)與錄音,去河邊找鬼桨螺。 笑死宾符,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的灭翔。 我是一名探鬼主播魏烫,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肝箱!你這毒婦竟也來(lái)了哄褒?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狭园,失蹤者是張志新(化名)和其女友劉穎读处,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(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
  • 文/蒙蒙 一泊窘、第九天 我趴在偏房一處隱蔽的房頂上張望熄驼。 院中可真熱鬧像寒,春花似錦、人聲如沸瓜贾。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)祭芦。三九已至筷笨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間实束,已是汗流浹背奥秆。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(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