当前位置: 首页 > news >正文

Android系列之 屏幕触控机制(一)

目录

1 Android native层传递点击事件

2 .Window和WindowManagerService的关系

2.1 ViewRootImpl 如何串联Window和WindowManagerService

2.2 ViewRootImpl和Window的关系

2.3 ViewRootImpl和WindowManagerService的关系


以下章节待分解:

3. ViewRootImpl的事件接收及分发

4. ViewGroup事件的分发机制

4.1 activity的视图创建流程

4.2 ViewGroup的事件分发流程

4.3 View的事件处理

5. 事件分发具体案例及解决方案

Android屏幕触控机制整体流程图

图1

1 Android native层传递点击事件

当用户点击屏幕时,屏幕会产生触摸事件,Linux内核会将触摸事件封装成event存到/dev/input/文件内。

inputReader从EventHub读取到事件并发送给InputDispatcher,

InputDispatcher分发至framework层 需要处理的地方。

下面我们来详细看一下framework层是如何接收点击事件并最终如何响应点击事件的

图2

2 .Window和WindowManagerService的关系

图3

2.1 ViewRootImpl 如何串联Window和WindowManagerService

当一个点击事件从native传递到framework时,viewRootImpl中的WindowInputEventReceiver()方法会最先响应点击事件。

而这个WindowInputEventReceiver()方法中的mInputChannel参数,是在WindowManagerService(以下简称wms )中和native层关联上的。

这个时候就有个疑问了,点击事件怎么和wms有关联了呢?其实wms他是一个重要的系统服务,用于窗口管理,他就是窗口的大主管,因为它记录了当前系统中所有窗口的完整信息,他还是点击事件的派发者,所以只有它才能判断出要把点击的事件投递给具体的某个应用进程进行处理。而应用进程如何接收的了?这里的应用进程可以理解成是一个应用层级的窗口Window。因为事件点击的目的地是应用层级的窗口Window。而wms和window中间需要一个纽带去衔接,这个中间的纽带就是ViewRootImpl, ViewRootImpl负责view 的绘制,也负责用户的点击操作处理。

下面就讲一下viewRootImp是如何创建并成为window和wms的纽带的。

2.2 ViewRootImpl和Window的关系

说起ViewRootImpl和window的关系,就要先看一下 ViewRootImpl是在哪里被创建的 ,这就要从handleResumeActivity流程开始看起

public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,String reason) { …… if (r.window == null && !a.mFinished && willBeVisible) { …… View decor = r.window.getDecorView(); …… ViewManager wm = a.getWindowManager(); …… wm.addView(decor, l); …… }

wm.addView的wm的实例对象就是WindowManagerImpl,其中的参数decor是DecorView对象

接着看WindowManagerImpl的addView方法做了什么

@Override public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { applyDefaultToken(params); mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow); }

又调用到了 WindowManagerGlobal的addView方法,可以看到ViewRootImpl在这里被创建了,并绑定了DecorView

public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { …… root = new ViewRootImpl(view.getContext(), display); …… mViews.add(view); mRoots.add(root); mParams.add(wparams); root.setView(view, wparams, panelParentView); …… }

2.2 ViewRootImpl和Window的关系

流程图大致介绍了ViewRootImpl是如何创建出来的,总结一下:在ActivityThread的handleResumeActivity()流程中,通过

WindowManager(WindowManagerImpl)的 addView() 实现了ViewRootImpl的创建。 此时我们应用层窗口Window就和ViewRootImpl建立了关联。

图4

2.3 ViewRootImpl和WindowManagerService的关系

而ViewRootImpl和wms的关联,是在ViewRootImpl的setview方法中

mWindowSession.addToDisplay()函数是添加窗口流程,对应的服务端就是WMS,而WMS又是个系统进程,所以这是个Binder跨进程调用方法,最终调用的是WMS的addWindow方法。而参数mInputChannel,它包括了发送和接收消息的功能封装。

最后声明了inputEvent方法,用来接受从底层传过来的点击事件

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { synchronized (this) { ...... requestLayout(); if ((mWindowAttributes.inputFeatures & WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL) == 0) { mInputChannel = new InputChannel(); } ...... res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes, getHostVisibility(), mDisplay.getDisplayId(), mWinFrame, mAttachInfo.mContentInsets, mAttachInfo.mStableInsets, mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel); ...... if (mInputChannel != null) { … // 声明了inputEvent方法,用来接受从底层传过来的点击事件 mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, Looper.myLooper()); } }
http://www.cnnetsun.cn/news/850873.html

相关文章:

  • Thinkphp和Laravel基于hadoop大数据的心脏病患者健康数据分析系统_
  • 408真题解析-2010-17-计组-TLB\Cache\Page关系
  • 免费DirectX修复工具——2026最新5种方法快速修复DirectX报错:AI一键解决最省心!
  • [特殊字符] Go语言从入门到实践(一):为什么Go能让程序员“少加班“?
  • 数据跨境、隐私泄露、审计溯源——出海企业三大安全必答题
  • 基于Spring Boot开发的大学生校内自习室座位预约系统源码+文档
  • Node.js 创建第一个应用
  • 手动处理CSV转Excel?Python批量转格式,不用逐个开文件
  • 基于深度学习YOLOv10的船舶分类识别检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)
  • 健康管理实训室厂家,一站式解决方案供应
  • Python 列表(List)
  • Spring Boot 异步编程:@Async 与线程池配置的最佳实践终极指南
  • Excel ADDRESS函数深度解析:动态构建单元格地址的艺术
  • 微信表情GIF传不上?GIF压缩到微信表情不模糊方法
  • 神秘大三角(洛谷P1355)
  • TCN-Transformer-LSTM组合模型回归+SHAP分析+新数据预测+多输出!深度学习可解释分析MATLAB代码
  • 数据清洗在大数据领域的发展趋势与展望
  • 拖拽式甘特图工具入门教程:轻松实现项目可视化与进度管理
  • 探秘 AgentRun丨动态下发+权限隔离,重构 AI Agent 安全体系
  • 加油卡小程序核心玩法拆解与运营逻辑分析
  • 目标检测算法应用工程师学习简介
  • 基于javaweb技术与SSM框架的智慧商城平台的设计与实现(11819)
  • KB1240/KB1241对射光电的使用
  • 程序员瑟瑟发抖!AI Agent全面接管编程:从“代码写出来“到“代码流出来“,不会用AI的即将被淘汰!
  • 【计算机毕设】
  • Tyr-[Hu-rasT24]-Lys ;Tyr-Gly-Ala-Val-Gly-Val-Gly-Lys-Ser-Lys
  • 如果生产环境Redis实例CPU使用率很高,比如达到90%以上,请问可能产生的原因有哪些? 如何解决?
  • Bun v1.3.7更新短评
  • 芦笋提词器 —— 线上工作汇报专用提词器推荐
  • 井下安全监控(有完整资料)