我们知道Android在View树内分发之前, 有一个比较奇怪的loop流程.
ViewRootImpl -> DecorView -> Activity -> PhoneWindow -> DecorView进行View树的分发.
这是因为ViewRootImpl拿到事件之后, 它根本不知道有Activity这个东西, 它只是直接持有DecorView, 所以它必须要吧事件传递给DecorView.
DecorView只持有Activity(Activity实现Window.Callback, DecorView持有这个Window.Callback), 所以它必须把事件传递给Activity.
Activity只知道有PhoneWindow, 所以要传递给PhoneWindow
PhoneWindow持有DecorView, 可以让DecorView进行View树的分发了.
看起来ViewRootImpl可以直接让DecorView进行View树的分发呀, 为啥不直接这样做呢, 为啥要层层包装呢? 为了解耦和吧.
其实只要记住这么一段代码就可以
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的所有消息会发送给mDecorView, mDecorView作为一个View, 他是没有办法私自决定怎么处理这个消息的.
所以mDecorView 就会上达天听, 交给Activity, Activity会交给他的首席大臣 PhoneWindow, PhoneWindow会交给真正干活的mDecorView, 实现这么一个循环.
网友评论