啟動一個Activity

Activity啟動

startActivity()

||

||

V

startActivityForResult()

||

||

V

ActivityStackSupervisor # realStartActivityLocked(){
    //...
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
            System.identityHashCode(r), r.info,
            new Configuration(mService.mConfiguration), r.compat,
            app.repProcState, r.icicle, results, newIntents, !andResume,
            mService.isNextTransitionForward(), profileFile, profileFd,
            profileAutoStop);
    //...
}

此處的app.threadIApplicationThread 帆阳,他的實現(xiàn)類是ActivityThread的內(nèi)部類ApplicationThread

那么看ApplicationThread中的shceduleLaunchActivity

@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) {
    //...
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

看下sendMessage做了什么

sendMessage()

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);
    }
    mH.sendMessage(msg);
}

搜索mH恩伺,發(fā)現(xiàn)是private class H extends Handler鹤树。是ActivityThread的內(nèi)部類铣焊,和主線程Looper關(guān)聯(lián),那么mHhandleMessage()就是在主線程里面執(zhí)行了罕伯。

搜索H類里面的H.LAUNCH_ACTIVITY曲伊,發(fā)現(xiàn)了:

public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null);//在這
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        break;
        //...
    }
}

handleLaunchActivity()

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //...
    //創(chuàng)建Application和Activity對象,并調(diào)用它們的生命周期
    Activity a = performLaunchActivity(r, customIntent);
    if(a!=null){
        //Activity#onResume
        handleResumeActivity(r.token, false, r.isForward,!r.activity.mFinished && !r.startsNotResumed);
    }
}

performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){
    ClassLoader cl = r.packageInfo.getClassLoader();
    //根據(jù)ClassLoader創(chuàng)建Activity對象
    Activity activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    //創(chuàng)建Application對象并調(diào)用App#onCreate
    Application app=r.packageInfo.makeApplication(false,mInstrumentation);
    //創(chuàng)建PhoneWindow追他,WindowManager坟募。并和Activity關(guān)聯(lián)
    activity.attach(...);
    //Activity#onCreate()
    mInstrumentation.callActivityOnCreate(activity, r.state);
    //Activity#onStart()
    activity.performStart();
    //...
}

r.pakageInfo.makeApplication()

public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
    if (mApplication != null) {
        return mApplication;
    }
    Application app = null;
    java.lang.ClassLoader cl = getClassLoader();
    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    mActivityThread.mAllApplications.add(app);
    instrumentation.callApplicationOnCreate(app);//調(diào)用App.onCreate()

activity.onAttach()

final void attach(...) {
    //實例化PhoneWindow
    mWindow = new PhoneWindow(this);
    mWindow.setCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    //實例化WindowManagerImpl,并和mWindow建立關(guān)聯(lián)湿酸。
    mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                             mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    mWindowManager = mWindow.getWindowManager();
}

看下是否在此處就new出一個WindowManager婿屹,點進setWindowManager()

public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
        boolean hardwareAccelerated) {
    //...
    mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}

點進createLocalWindowManager(this)

public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
    //的確推溃,在這里實例化了WindowManagerImpl
    return new WindowManagerImpl(mDisplay, parentWindow);
}

handleResumeActivity()

final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
boolean reallyResume) {
    //Activity#onResume()
    ActivityClientRecord r = performResumeActivity(token, clearHide);
    r.window = r.activity.getWindow();
    View decor = r.window.getDecorView();
    //讓DecorView變的不可見
    decor.setVisibility(View.INVISIBLE);
    //WindowManager在Activity#onAttach中已經(jīng)被實例化了
    ViewManager wm = a.getWindowManager();
    WindowManager.LayoutParams l = r.window.getAttributes();
    //WindowManager#addView昂利,將DecorView添加到Window中。
    wm.addView(decor, l);
}

現(xiàn)在Activity的onResume都執(zhí)行完了,執(zhí)行到了WindowManager#addView蜂奸。


WindowManager

WindowManager接口繼承自ViewMananger犁苏。ViewManager意思是:view管理者

public interface ViewManager{
    public void addView(View view, ViewGroup.LayoutParams params);
    public void updateViewLayout(View view, ViewGroup.LayoutParams params);
    public void removeView(View view);
}

因此WindowManager也具有管理View管理者的能力,他的實現(xiàn)類是WindowManagerImpl扩所∥辏看看他的addView在做什么。

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

mGlobal是WindowManagerGlobal祖屏,從命名方式和getInstance看出助赞,很明顯的全局單例。
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
看下WindowManagerGlobal中的4個引用

public final class WindowManagerGlobal {
    ...
    //放著所有的DecorView袁勺。(有的博客說放著所有的View雹食,但是WMG里面用了mViews.add()的地方只有一個,而且只會傳入DecorView期丰。因此我認(rèn)為是只放DecorView)
    private final ArrayList<View> mViews = new ArrayList<View>();
    //放著所有的ViewRootImpl
    private final ArrayList<ViewRootImpl> mRoots = new ArrayList<ViewRootImpl>();
    //放著所有的WindowManager.LayoutParams
    private final ArrayList<WindowManager.LayoutParams> mParams =new ArrayList<WindowManager.LayoutParams>();
    //放著所有正在被刪除的View群叶。
    private final ArraySet<View> mDyingViews = new ArraySet<View>();
    ...
}

接著mGlobal.addView里面在做什么。

public void addView(View view, ViewGroup.LayoutParams params,
        Display display, Window parentWindow) {
    final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
    ViewRootImpl root;
    //實例化了ViewRootImpl钝荡,調(diào)用他的構(gòu)造方法街立。
    root = new ViewRootImpl(view.getContext(), display);
    view.setLayoutParams(wparams);
    mViews.add(view);
    mRoots.add(root);
    mParams.add(wparams);
    // do this last because it fires off messages to start doing things
    root.setView(view, wparams, panelParentView);//調(diào)用了ViewRootImpl#setView。跟進去看下
}

ViewRootImpl#setView

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
    mView = view;
    // Schedule the first layout -before- adding to the window
    // manager, to make sure we do the relayout before receiving
    // any other events from the system.
    requestLayout();
    //將該Window添加到屏幕埠通。
    //mWindowSession實現(xiàn)了IWindowSession接口赎离,它是Session的客戶端Binder對象.
    //addToDisplay是一次AIDL的跨進程通信,通知WindowManagerService添加IWindow
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
        getHostVisibility(), mDisplay.getDisplayId(),
        mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
        mAttachInfo.mOutsets, mInputChannel);
    view.assignParent(this);
}

requestLayout()里面調(diào)用scheduleTraversals();然后調(diào)用Choreographer編舞者的內(nèi)部的一系列方法植阴,用Handler和Looper,把doTraversals()放到主線程去輪詢蟹瘾。然后調(diào)用的就是三大遍歷,測量掠手,布局憾朴,繪制。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喷鸽,一起剝皮案震驚了整個濱河市众雷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌做祝,老刑警劉巖砾省,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異混槐,居然都是意外死亡编兄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門声登,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狠鸳,“玉大人揣苏,你說我怎么就攤上這事〖妫” “怎么了卸察?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铅祸。 經(jīng)常有香客問我坑质,道長,這世上最難降的妖魔是什么临梗? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任涡扼,我火速辦了婚禮,結(jié)果婚禮上夜焦,老公的妹妹穿的比我還像新娘壳澳。我一直安慰自己,他們只是感情好茫经,可當(dāng)我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著萎津,像睡著了一般卸伞。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锉屈,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天荤傲,我揣著相機與錄音,去河邊找鬼颈渊。 笑死遂黍,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的俊嗽。 我是一名探鬼主播雾家,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼绍豁!你這毒婦竟也來了芯咧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤竹揍,失蹤者是張志新(化名)和其女友劉穎敬飒,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芬位,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡无拗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了昧碉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片英染。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡阴孟,死狀恐怖税迷,靈堂內(nèi)的尸體忽然破棺而出永丝,到底是詐尸還是另有隱情,我是刑警寧澤箭养,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布慕嚷,位于F島的核電站,受9級特大地震影響毕泌,放射性物質(zhì)發(fā)生泄漏喝检。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一撼泛、第九天 我趴在偏房一處隱蔽的房頂上張望挠说。 院中可真熱鬧,春花似錦愿题、人聲如沸损俭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽杆兵。三九已至,卻和暖如春仔夺,著一層夾襖步出監(jiān)牢的瞬間琐脏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工缸兔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留日裙,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓惰蜜,卻偏偏與公主長得像昂拂,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蝎抽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,685評論 2 360

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