Android4.4之Input模块笔记

在InputReader从EventHub中获取输入事件,包含触摸屏事件、物理按键事件等,然后转交给InputDispatcher线程,InputDispatcher经过筛选,过滤输入事件。对于触摸事件通过调用findTouchedWindowTargetsLocked()函数找到合适的InputTarget,然后通过dispatchEventLocked()->prepareDispatchCycleLocked()->enqueueDispatchEntriesLocked()->enqueueDispatchEntryLocked()->  connection->outboundQueue.enqueueAtTail(dispatchEntry)添加到与InputTarget一一对应的connection中的一个队列中。如果之前该队列无数据,并且当前触摸事件已成功加入该队列,则继续调用startDispatchCycleLocked()函数进行分发处理。在startDispatchCycleLocked()中,有一个while循环,该循环从connection->outboundQueue队列中取出输入事件,如果该输入事件是按键(key)事件,则调用connection->inputPublisher.publishKeyEvent()函数,如果是触摸事件则调用connection->inputPublisher.publishMotionEvent()。publishKeyEvent()和publishMotionEvent()都是调用mChannel->sendMessage()将输入事件发送出去。mChannel是一个C++层InputChannel对象,该对象的赋值过程如下:registerInputChannel()->new Connection->Connection()构造函数->InputPublisher()构造函数。事实上,在registerInputChannel()被调用之前,ViewRootImple在增加一个窗口时调用ViewRootImpl.setView()->mWindowSession.addToDisplay()-WindowManagerService.addWindow(),在addWindow()中会创建一对InputChannel(Nativie层),实际上是创建一对Socket,服务端InputChanel被WMS注册到InputDispatcher中,客户端InputChannel被返回给ViewRootImpl,ViewRootImpl将客户端InputChannel作为参数new一个InputEventReceiver对象,在InputEventReceiver()构造函数中继续调用nativeInit()函数来创建一个native层的NativeInputEventReceiver对象,前面创建的客户端InputChannel会保存在该对象中。

总结:WMS会调用native层接口创建一对套接字,服务端保存在InputDispatcher中,客户端保存在NativeInputEventReceiver中(android_view_inputEventReceiver.cpp)。

很容易想到输入事件是从InputDispatcher流向NativeInputEventReceiver中。在创建一个native层的NativeInputEventReceiver对象后会立即调用NativeInputEventReceiver->initialize(),该函数调用mMessageQueue->getLooper()->addFd(fd,0,
events, this, NULL)将客户端socket句柄添加到Looper的轮询队列中,参数this指向NativeInputEventReceiver本身,意味着只要服务端InputDispatcher发送输入事件,客户端收到这个事件,就调用NativeInputEventReceiver的某个函数,具体调用哪个函数,自然是NativeInputEventReceiver实现了LooperCallback的接口函数handleEvent()。但此时收到的事件只是代表socket客户端有事件来,并没有把具体的事件读取出来,这点需要注意。

总结:客户端收到输入事件,即调用NativeInputEventReceiver->handleEvent()函数。

在handleEvent()函数中,继续调用consumeEvents()->mInputConsumer.consume()->mChannel->receiveMessage(&mMsg)将具体输入事件读取出来,然后调用env->CallVoidMethod(receiverObj.get(), gInputEventReceiverClassInfo.dispatchInputEvent,seq,
inputEventObj),可以知道native层读取输入事件后,然后会回调java层InputEventReceiver.java中的dispatchInputEvent()函数。事实上,

dispatchInputEvent继续调用onInputEvent(event);此时可能并不调用InputEventReceiver类中的onInputEvent()方法,而是调用子类onInputEvent()方法。在ViewRootImpl中存在WindowInputEventReceiver类型变量mInputEventReceiver,WindowInputEventReceiver类继承InputEventReceiver,并实现onInputEvent()方法由此可得出结论:native层socket客户端读取输入事件,最终调用InputEventReceiver类子类的onInputEvent()方法,ViewRootImpl继承InputEventReceiver,因此ViewRootImpl.onInputEvent()将被调用。

总结:对于一般的触摸屏事件最终处理者是ViewRootImpl类,对于输入法则处理者是IInputMethodSessionWrapper类,当然WMS是不会处理这些输入事件的。

继续研究ViewRootImpl.onInputEvent()函数,onInputEvent()->doProcessInputEvents()->deliverInputEvent(),

Android4.4之Input模块笔记

时间: 2024-11-11 04:44:29

Android4.4之Input模块笔记的相关文章

Android4.4   Input模块笔记

在InputReader从EventHub中获取输入事件,包含触摸屏事件.物理按键事件等,然后转交给InputDispatcher线程,InputDispatcher经过筛选,过滤输入事件.对于触摸事件通过调用findTouchedWindowTargetsLocked()函数找到合适的InputTarget,然后通过dispatchEventLocked()->prepareDispatchCycleLocked()->enqueueDispatchEntriesLocked()->e

Django模块笔记【一】

入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/topics/ *该笔记将对各个模块进行单独介绍 *Model&Database 1. 模型(models) 模型是数据的唯一信息源,它指示了数据的域(fields)和行为(behaviors).每个模型都对应一个数据库表. ①每个模型都是django.db.models.Model的子类:②模型的每个属性代表了数据库的域:③数据库入口API,参考making queries部分. 比如, 1 fro

Django模块笔记【三】

入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/topics/ *该笔记将对各个模块进行单独介绍 *Forms 1. 使用表单(Working with forms) 只要网站涉及到访问者的输入操作,那么就必须用到表单.在HTML中,表单是<form>...</form>中的语句集合. GET和POST是HTTP处理表单仅有的两种方式.Django中使用Form类表示表单. 对使用方法进行简单举例: 1 # forms.py 2 3

ldd3-2 构造和运行模块:Hello World模块笔记

实验环境: 按照之前的搭建方法,已经在Ubuntu 5.04版本上构建了linux原始的2.6.10版本内核树: GCC是用的安装镜像自带的版本: 一切准备就绪后对虚拟机做了快照,防止内核损坏: 因为Ubuntu 5.04虚拟机下编程很麻烦,所以编码和调试都不在虚拟机下运行了: 编辑在windows下运行,然后把代码文件通过Xftp传输到虚拟机里: 调试的话通过Xshell: 笔记基本是按照书上小结的标题来的,每个标题能做实验的就做实验,理论性的就小结一下,不易过多记忆,因为没代码实践,理论也理

Django模块笔记【六】

入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/topics/ *该笔记将对各个模块进行单独介绍 *migration&Managing files&Testing in Django 1. migration的命令 migrate命令负责应用migrations,同时也负责撤销migrations以及查看他们的状态. makemigrations基于对模型的改变,创建新的migrations. sqlmigrate为migration显示S

Django模块笔记【二】

入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/topics/ *该笔记将对各个模块进行单独介绍 * HTTP Request Handlers 1. URL dispatcher URL在名为URLconf的Python模块中创建,该模块提供了URL模式(正则表达式)和Python函数(视图)之间的映射. URLconf举例如下: 1 from django.conf.urls import url 2 3 from . import views

Django模块笔记【五】

入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/topics/ *该笔记将对各个模块进行单独介绍 *Class-based views 视图是接受请求并返回响应的可调用对象. 1. 用法举例 1 from django.conf.urls import url 2 from django.views.generic import TemplateView 3 4 urlpatterns = [ 5 url(r'^about/', TemplateV

Django模块笔记【四】

入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/topics/ *该笔记将对各个模块进行单独介绍 *template 1. 配置(Configuration) 1 TEMPLATES = [ 2 { 3 'BACKEND': 'django.template.backends.django.DjangoTemplates', 4 'DIRS': [], 5 'APP_DIRS': True, 6 'OPTIONS': { 7 # ... some

MTK6572 android4.4上串口模块的调试

年前调试了一下用mtk的uart1口来外接外部模块,拓展为2个com口.写此文的目前主要是整理一下思路. 拓展ic的型号是WK2114: WK2114 原理框图 由上图可以看到首先得把主接口测试ok. mtk6572的uart1默认是用来打log用的,所以要修改权限  chmod 0660 /dev/ttyMT0 chown system system /dev/ttyMT0 修改过后可以用在手机上装一个com口apk连接电脑测试,看看是否正常.一般这步是没问题的. 另外有可能会碰到不稳定的情况