Android事件分发机制

一. 学前基础(了解Activity,Window,DecorView,ViewRoot的关系):

3985563-e773ab2cb83ad214.png

1. Activity:

Activity只是控制生命周期和处理事件,并不负责视图控制。真正控制视图的是PhoneWindow。一个Activity包含一个PhoneWindow,PhoneWindow才是真正代表一个窗口。Activity就像一个控制器,统筹视图的添加与显示,以及通过其他回调方法,来与PhoneWindow、以及View进行交互。

2. PhoneWindow:

PhoneWindow是视图的承载器,内部持有一个 DecorView,而这个DecorView才是 view 的根布局。PhoneWindow是Window唯一实现的子类。PhoneWindow中有个内部类DecorView,通过创建DecorView来加载Activity中设置的布局R.layout.activity_main。PhoneWindow 通过WindowManager将DecorView加载其中,并将DecorView交给ViewRoot,进行视图绘制以及其他交互。

3. DecorView:

DecorView是FrameLayout的子类,它被认为是Android视图树的根视图。DecorView作为顶级View,一般情况下它内部包含一个竖直方向的LinearLayout,在这个LinearLayout里面有上下三个部分,上面是个ViewStub,延迟加载的视图(应该是设置ActionBar,根据Theme设置),中间的是标题栏(根据Theme设置,有的布局没有),下面的是内容栏。 具体情况和Android版本及主体有关,以其中一个布局为例,如下所示:

<FrameLayout
    style="?android:attr/windowTitleBackgroundStyle"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/windowTitleSize">

    <TextView
        android:id="@android:id/title"
        style="?android:attr/windowTitleStyle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@null"
        android:fadingEdge="horizontal"
        android:gravity="center_vertical" />
</FrameLayout>

<FrameLayout
    android:id="@android:id/content"
    android:layout_width="match_parent"
    android:layout_height="0dip"
    android:layout_weight="1"
    android:foreground="?android:attr/windowContentOverlay"
    android:foregroundGravity="fill_horizontal|top" />
复制代码

在Activity中通过setContentView所设置的布局文件其实就是被加到内容栏之中的,成为其唯一子View,就是上面的id为content的FrameLayout中,在代码中可以通过content来得到对应加载的布局。

ViewGroup content = (ViewGroup)findViewById(android.R.id.content);
ViewGroup rootView = (ViewGroup) content.getChildAt(0);
复制代码

4. ViewRoot

所有View的绘制以及事件分发等交互都是通过它来执行或传递的。

ViewRoot对应ViewRootImpl类,它是连接WindowManagerService和DecorView的纽带,View的三大流程(测量(measure),布局(layout),绘制(draw))均通过ViewRoot来完成。

ViewRoot并不属于View树的一份子。从源码实现上来看,它既非View的子类,也非View的父类,但是,它实现了ViewParent接口,这让它可以作为View的名义上的父视图。ViewRoot继承了Handler类,可以接收事件并分发,Android的所有触屏事件、按键事件、界面刷新等事件都是通过ViewRoot进行分发的。

5. 总结

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

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

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

二.事件分发机制—未完待续

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享