美文网首页Android开发Android开发经验谈Android葵花宝典
从源码角度分析Activity、Window和DecorView

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

作者: 肖邦kaka | 来源:发表于2018-05-29 10:11 被阅读46次

    前言

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

    相关文章

      网友评论

        本文标题:从源码角度分析Activity、Window和DecorView

        本文链接:https://www.haomeiwen.com/subject/oleyjftx.html