前言
最近想出一篇Android事件分发机制的文章,但是根据很多小伙伴反馈在理解Android事件分发机制之前都不是很明白Activity、Window和DecorView之间的关系,导致在学习Android事件分发机制上理解很费劲,本文将从源码角度带你分析Activity、Window和DecorView之间的关系,让你彻彻底底搞明白。
Activity、Window和DecorView之间的关系图
看图来说就是一种简单的包含关系(图画得比较糙),Activty里面持有一个Window,这个Window有一个唯一实现子类PhoneWindow,而PhoneWindow对象里面又持有一个DecorView对象,这个DeCorView继承自FrameLayout,FragmentLayout是ViewGroup的子类,也就是说DecorView是ViewGroup的间接子类。先有一个大体的概念,下面我会从源码角度带着大家一起分析。
源码分析
每一个Activity里面都持有一个Window对象
public class Activity extends ContextThemeWrappe{
private Window mWindow;
mWindow = new PhoneWindow(this);
}
Window是一个抽象类,它有一个唯一实现子类PhoneWindow,PhoneWindow是窗口,并不具备多少View的能力,但是它持有一个DecorView对象。这个DecorView对象很重要,是所有View的顶层,也就是说所有View的最外层View。
public class PhoneWindow extends Window{
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
}
DecorView继承自FrameLayout,FrameLayout继承自ViewGroup,所以DecorView是ViewGroup的间接子类。
public class DecorView extends FrameLayout {
}
根据这些简单的源码,我们就可以很清楚地知道了Activity、Window和DecorView的g。本文前言中也有提到,之所以写这篇文章,是为了让小伙伴们更好地理解Android事件分发机制,事件是如何从Activity到ViewGroup,下面我就会详细地跟大家说一下这个问题。
事件分发从Activity到ViewGroup
首先,我们要明确,事件分发机制都是从Activity》》ViewGroup》》View这种顺序开始分发,而在Activity在向ViewGroup分发的过程中,Activity、Window和DecorView就起到了至关重要的作用,下面我们仍然从源码的角度进行分析。
事件分发机制最重要的三个方法dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent ,我们先从Activity里面的dispatchTouchEvent开始分析。
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
//手机屏保的方法,空实现,不关心(下一篇文章会做详细的讲解)
onUserInteraction();
}
//事件开始传递
if (getWindow().superDispatchTouchEvent(ev)) {
return true;
}
return onTouchEvent(ev);
}
getWindow()方法获取的对象是PhoneWindow,之前文中已经提到PhoneWindow是Window唯一实现子类
我们看一下PhoneWindow的superDispatchTouchEvent的源码
@Override public boolean superDispatchTouchEvent(MotionEvent event) {
return mDecor.superDispatchTouchEvent(event);
}
这其中mDecor就是DecorView对象,继续看一下DecorView的superDispatchTouchEvent方法
public boolean superDispatchTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
}
调用父类的dispatchTouchEvent,之前文章多次提到了ViewGroup是DecorView的间接父类,所以事件最终传递给了ViewGroup,至此就完成了事件从Activity到ViewGroup的传递过程。
最后
Activity、Window和DecorView之间的关系其实一点也不复杂,但是却很重要,不仅仅是在事件分发机制上,在setContentView等相关把View添加到Activity都起了至关重要的作用,而推出本文的作用是为了下一篇Android事件分发机制的详解做准备,感兴趣的小伙伴可以关注一下,今天都是源码分析就没有github上的代码了。