从源码角度分析Activity、Window和DecorView的关系

前言

最近想出一篇Android事件分发机制的文章,但是根据很多小伙伴反馈在理解Android事件分发机制之前都不是很明白Activity、Window和DecorView之间的关系,导致在学习Android事件分发机制上理解很费劲,本文将从源码角度带你分析Activity、Window和DecorView之间的关系,让你彻彻底底搞明白。

Activity、Window和DecorView之间的关系图

从源码角度分析Activity、Window和DecorView的关系
关系图.png

看图来说就是一种简单的包含关系(图画得比较糙),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上的代码了。

上一篇:PHP常用库函数介绍+常见疑难问题解答


下一篇:IIS 无法读取配置节"system.web.extensions",因为它缺少节声明