Activity、Window、DecorView、ViewRootImpl(ViewRoot)

(1)Activity、Window、DecorView

Window 是附属在 Activity 中的,其具体的实现是 PhoneWindow,每一个 Activity 都会有一个 Window。

而 DecorView 又是附属在 PhoneWindow 中的。

Window 用于在 Activity 中控制顶级 View 的外观和行为策略。

而 DecorView 是由 Window 的实现类 PhoneWindow 持有的成员变量,前面说的顶级 View 即 DecorView。

DecorView 一般就是当前界面的底层容器(即 setContentView 所设置的 View 的最顶级父容器,其继承自 FrameLayout ),通过 Activity#getWindow().getDecorView() 可以获得。

注意,DecorView 并不是 ContentView 的直接父 View。DecorView 只有一个唯一的子 View,一般是一个 LinearLayout(被称为 mContentRoot),然后该 LinearLayout 就包含了 ActionBar 等,当然还包括 ContentView 的直接父布局(即一个 ViewGroup,被称为 mContentParent),然后 mContentParent 则包含设置的 ContentView。

比如 Window 控制行为策略:

当点击事件到达 Activity 的时候,Activity 就会通过内部的 PhoneWindow 将事件进一步分发,具体过程如下:

// Activity.java
public boolean dispatchTouchEvent(MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_DOWN) {
        onUserInteraction();
    }
    // getWindow() 会得到内部的成员变量 mWindow(PhoneWindo 类型)
    if (getWindow().superDispatchTouchEvent(ev)) {
        return true;
    }
    return onTouchEvent(ev);
}

// PhoneWindow.java
@Override
public boolean superDispatchTouchEvent(MotionEvent event) {
	// mDecor 即 DecorView 实例
    return mDecor.superDispatchTouchEvent(event);
}



// DecorView.java
public boolean superDispatchTouchEvent(MotionEvent event) {
	// DecorView 继承自 FrameLayout,
	// 因此 super.dispatchTouchEvent() 即调用 ViewGroup#dispatchTouchEvent()
    return super.dispatchTouchEvent(event);
}

(2)ViewRoot 与 DecorView

ViewRoot 是概念上的名词,在 Android 源码中并不实际存在,而其实际的实现者为 ViewRootImpl。

ViewRootImpl 实现了 ViewParent 接口,但它既不是 View 的子类,也非 View 的父类。

但是它在逻辑上是作为 DecorView 的 Parent 而存在的。(更进一步的可参阅:屏幕刷新机制 笔记整理)

而且 ViewRootImpl 是连接 WindoManager 与 DecorView 的纽带。

ViewRootImpl 管理着 DecorView 及其子 View 的刷新、绘制等流程。

有些文章说 ViewRootImpl 会分发屏幕的点击事件,准确的说应该是感知硬件的产生的物理事件,然后传递给上层。

当用户点击屏幕产生一个触摸行为,这个触摸行为则是通过底层硬件来传递捕获,然后交给ViewRootImpl,接着将事件传递给 DecorView,而 DecorView 再交给 PhoneWindow,PhoneWindow 再交给 Activity,然后接下来就是我们常见的 View 事件分发了。

硬件 -> ViewRootImpl -> DecorView -> PhoneWindow -> Activity。

而看到(1)中的源码,对于事件点击事件的分发,则是经由 Activity 的 window 直接传递到了 DecorView 上,从而进行 ViewGroup 级别的传递,这里就没有涉及到 ViewRootImpl 了。

参考文章:ViewRootImpl源码分析事件分发


(3)DecorView 的显示

通过setContentView()设置的界面,为什么在onResume()之后才对用户可见呢?
可以参考 简析Window、Activity、DecorView以及ViewRoot之间的错综关系 第三点

Activity 就像个控制器,不负责视图部分。Window 像个承载器,装着内部视图。DecorView 就是个顶层视图,是所有 View 的最外层布局。ViewRoot 像个连接器,负责沟通,通过硬件的感知来通知视图,进行用户之间的交互。


参考文章:
1、《Android 开发艺术探索》
2、屏幕刷新机制 笔记整理
3、简析Window、Activity、DecorView以及ViewRoot之间的错综关系

发布了148 篇原创文章 · 获赞 27 · 访问量 6万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览