Android事件从底层传递到Activity过程

Android中事件上层的分发、拦截、处理还是比较好理解的,那么事件是如何从点击屏幕传到Activity,再有Activity分发给它自己的View的呢?

这里可能要分为两层:1、手机点击屏幕 事件传回–> Activity;2、Activity如何分发给子ViewGroup、View?

一、关于屏幕点击后的流程看图:

二、屏幕点击后,事件如何监听?如何分发?
1.1 在深入看底层代码前我们先要了解几个知识。
  • 1、屏幕事件有驱动保存在/dev/input/event0文件中

  • 2、底层对/dev/input/event0主要使用Epoll+iNotify机制监听

1.2 下图是SystemServer进程开始IMS后,Native监听到事件后,准备由SystemServer进程发送到App进程的Activity阶段。
  • 1、SystemServer实例化了InputManagerService实例,而上层的IMS实际依赖Native层的IMS来起作用。
  • 2、Native层IMS会实例化一个EventHub和InputManager实例,EventHub主要封装了Epoll和iNotify机制,用来实现对/dev/input文件进行监控
  • 3、InputManager构造方法中会实例InputReader和InputDispatcher,它们分别对事件读取和分发
  • 4、并且新建两个线程InputReaderThread和InputDispatcherThread来处理有关读取事件和分发事件的事项
  • 5、InputReaderThread线程开启后,通过epoll_wait阻塞,只到有事件发生(epoll_ctl)就会继续执行,封装事件,并将事件存储在mInboundQueue队列中。
  • 6、InputDispatcherThread线程开启后,会去mInboundQueue队列中取事件,有就开始分发
  • 7、因为此时IMS处于SystemServer进程,事件要发送给Activity(App进程)。这是跨进程通信。但是他这里不是使用Binder来通信,而是使用的SocketPair。
  • 8、下图到了InputTransport.cpp publishMotionEvent()方法中 mChannel -> sendMessage(&msg)就是开始向上层Activity传递事件了。

三、Native底层获取信息后,如何跨进程通信传给上层App的Activity?
3.1 SystemServer进程和App进程建立链接用于事件传递
  • 1、前面知道ActivityThread调到了handleResumeActivity方法,通过mWM.addView。最终会到ViewRootImpl的setView方法。
  • 2、setView方法里,通过Session通信来到了WMS.addWindow
  • 3、WMS.addWindow会调用到WindowState.openInputChannel方法
  • 4、WindowState.openInputChannel会通过InputChannel.openInputChannelPair去底层创建两个SocketPair实例,一个用于写,一个用于读取。
  • 5、创建好的两个SocketPair,会同时作用于一块区域,一个给Native层用于写事件,一个会调给上层用于读事件。
  • 6、到这里就是建立好了SystemServer进程和App进程之间的链接,它们可以通信了。
3.2 链接建立好后,Native层事件会调给Activity
  • 1、回到ViewRootImp.setView方法,在建立链接后,会实例化一个WindowInputEventReceiver对象,它将用于接受底层发送过来的事件。
  • 2、WindowInputEventReceiver继承至InputEventReceiver,InputEventReceiver构造方法中会调用nativeInit,会对应构建一个NativeInputEventReceiver实例。并将InputChannel和MessageQueue传入。
  • 3、NativeInputEventReceiver就类似于Handler机制,在consumeEvents中收到InputDispatcher发出的事件。将会回调InputEventReceiver.java的dispatchToucheEvent方法
  • 4、然后因为WindowInputEventReceiver是InputEventReceiver子类,会调用到WindowInputEventReceiver的onInputEvent方法。
  • 5、一路调用最终回到ViewPostimeInputStage的processPointerEvent方法
  • 6、而processPointerEvent方法中会调用View的dispatchPointerEvent方法
  • 7、dispatchPointerEvent方法中会调用dispatchTouchEvent方法,而在ViewRootImpl中mView实际是DecorView。
  • 8、那么就进入到DecorView的dispatchTouchEvent方法,在该方法中会调用mWindow.getCallback().dispatchTouchEvent方法。
  • 9、而在Activity的attach方法中又mWindow.setCallback(this),所以mWindow.getCallback()其实就是Activity对象,Activity也实现了Window.Callback接口。
  • 10、到这事件就到了Activity的dispatchTouchEvent来了,接下来就是应用层,Activity分发给它的子ViewGroup和子View了。

作者:天上飘的都是浮云
原文链接:(https://www.jianshu.com/p/84cf443cfa75)

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
在这里插入图片描述
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

全套视频资料:

一、面试合集

在这里插入图片描述
二、源码解析合集
在这里插入图片描述

三、开源框架合集
在这里插入图片描述
欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值