从源码角度分析Activity、Window和DecorView的关系
前言
最近想出一篇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上的代码了。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
17.源码阅读(Touch事件分发)
有这样一个布局,Activity中有一个ViewGroup,ViewGroup中又放了一个View,我重写了Activity的dispatchTouchEvent和onTouchEvent,重写了ViewGroup的dispatchTouchEvent,onInterceptTouchEvent和onTouchEvent,重写了View的dispatchTouchEvent和onTouchEvent,然后触摸一下TestTouchView,看看控制台打印了什么结果 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="ver...
- 下一篇
Android分页加载刷新AsyncListUtil中DataCallback的refreshData()
Android分页加载刷新AsyncListUtil中DataCallback的refreshData() Android分页加载刷新AsyncListUtil中DataCallback的refreshData()函数,返回值控制分页总数据量。如果返回一个既定的整型数据,那么AsyncListUtil的分页将在这个整型数据范围内分页和刷新,而不会超出这个范围。refreshData的实现源代码: /** * Refresh the data set and return the new data item count. * * <p> * If the data is being accessed through {@link android.database.Cursor} this is where * the new cursor should be created. * * @return Data item count. */ @WorkerThread public abstract int refreshData(); 实际的开发过程中,既然是分页,通常不确定...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Mario游戏-低调大师作品
- CentOS关闭SELinux安全模块
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,CentOS7官方镜像安装Oracle11G