我們知道Android在View樹(shù)內(nèi)分發(fā)之前, 有一個(gè)比較奇怪的loop流程.
ViewRootImpl -> DecorView -> Activity -> PhoneWindow -> DecorView進(jìn)行View樹(shù)的分發(fā).
這是因?yàn)閂iewRootImpl拿到事件之后, 它根本不知道有Activity這個(gè)東西, 它只是直接持有DecorView, 所以它必須要吧事件傳遞給DecorView.
DecorView只持有Activity(Activity實(shí)現(xiàn)Window.Callback, DecorView持有這個(gè)Window.Callback), 所以它必須把事件傳遞給Activity.
Activity只知道有PhoneWindow, 所以要傳遞給PhoneWindow
PhoneWindow持有DecorView, 可以讓DecorView進(jìn)行View樹(shù)的分發(fā)了.
看起來(lái)ViewRootImpl可以直接讓DecorView進(jìn)行View樹(shù)的分發(fā)呀, 為啥不直接這樣做呢, 為啥要層層包裝呢? 為了解耦和吧.
其實(shí)只要記住這么一段代碼就可以
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId) {
...
ViewRootImpl root;
View panelParentView = null;
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
try {
root.setView(view, wparams, panelParentView, userId);
} catch (RuntimeException e) {
...
throw e;
}
}
}
就是ViewRootImpl 只持有mDecorView, 所有ViewRootImpl的所有消息會(huì)發(fā)送給mDecorView, mDecorView作為一個(gè)View, 他是沒(méi)有辦法私自決定怎么處理這個(gè)消息的.
所以mDecorView 就會(huì)上達(dá)天聽(tīng), 交給Activity, Activity會(huì)交給他的首席大臣 PhoneWindow, PhoneWindow會(huì)交給真正干活的mDecorView, 實(shí)現(xiàn)這么一個(gè)循環(huán).