本文转载自:http://blog.csdn.net/u013491946/article/details/72638954

版权声明:免责声明: 本人在此发文(包括但不限于汉字、拼音、拉丁字母)均为随意敲击键盘所出,用于检验本人电脑键盘录入、屏幕显示的机械、光电性能,并不代表本人局部或全部同意、支持或者反对观点。如需要详查请直接与键盘生产厂商法人代表联系 .挖井挑水无水表,不会网购无快递

目录(?)[-]

  1. input服务的启动
  2. InputDispatcher分发
  3. InputReader读取

上一篇Linux/Android——input系统之 kernel层 与 frameworks层交互 (五)  中有介绍kernel层一下以及与Android这边frameworks层之间的联系,算是打通android 应用层与 kernel驱动层,对整个input系统的学习是至关重要的,其中frameworks层只是简单记录了几个接入点,这里开始分析frameworks层的细节部分。

撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/42392311

input服务的启动:

android启动的时候会启动很多个service,这个可以参考SystemServer.Java ,会启动InputManagerService这个服务:

[objc] view plain copy
  1. Slog.i(TAG, "Input Manager");
  2. inputManager = new InputManagerService(context, wmHandler);
  3. ...
  4. ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

直接看InputManagerService.java中的start函数:

[java] view plain copy
  1. public void start() {
  2. Slog.i(TAG, "Starting input manager");
  3. nativeStart(mPtr);   //调用了本地方法,JNI对应的cpp 在server下的jni目录下
  4. ...
  5. }

这个牵扯到android的server的jni,最开始是在SystemServer中加载android_server这个动态库,

至于这个动态库的编译可参考/frameworks/base/services/jni/Android.mk中的内容

所以在调用这个nativeStart方法时,相关的动态库已经加载到SystemServer的进程中。

先看下这个start函数在jni文件中的实现,frameworks/base/services/jni/com_android_server_input_InputManagerService.cpp中:

[objc] view plain copy
  1. static void nativeStart(JNIEnv* env, jclass clazz, jint ptr) {
  2. NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);  //这个NativeInputManager 是在上面InputMangerService构造的时候调用nativeInit时new出来的
  3. status_t result = im->getInputManager()->start(); //这里是调用了NativeInputManager中的InputManager中的start方法,同样这个InputManager是NativeInputManager构造的时候new出来的
  4. if (result) {
  5. jniThrowRuntimeException(env, "Input manager could not be started.");
  6. }
  7. }

其实熟悉JNI的话,我分析到这里,就应该差不多了。。对于JNI 不是很了解的话可以参考我之前的博客:Andorid——ubuntu下的 NDK / JNI

看下NativeInputManager构造函数中的:

[objc] view plain copy
  1. sp<EventHub> eventHub = new EventHub();
  2. mInputManager = new InputManager(eventHub, this, this);

这里的JNI部分就不多说了,现在就看这个InputManager的start方法,上面提到到Android.mk,可以看到include了一个libinput的动态库,

而这个动态库的路径是在/frameworks/base/services/input下,这就明了啦.此目录下有InputManager.cpp . EventHub.cpp等

直接看start:

[objc] view plain copy
  1. status_t InputManager::start() {
  2. status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);  //这个mDispatcherThread是在InputManager构造函数里调用initialize初始化,这里很明显启动了这个名为InputDispatcher的线程
  3. if (result) {
  4. ALOGE("Could not start InputDispatcher thread due to error %d.", result);
  5. return result;
  6. }
  7. result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY); //同上,开启线程
  8. if (result) {
  9. ALOGE("Could not start InputReader thread due to error %d.", result);
  10. mDispatcherThread->requestExit();
  11. return result;
  12. }
  13. return OK;
  14. }

到这里算是看到真面目的感觉,看这两个线程,字面意思,一个是分发给input事件给当前的activity的,一个是读取从下层发上来的input事件的

InputDispatcher分发:

从上面的线程启动分析:

[objc] view plain copy
  1. bool InputDispatcherThread::threadLoop() {
  2. mDispatcher->dispatchOnce();
  3. return true;
  4. }

调用分发一次的函数:

[objc] view plain copy
  1. void InputDispatcher::dispatchOnce() {
  2. nsecs_t nextWakeupTime = LONG_LONG_MAX;
  3. { // acquire lock
  4. AutoMutex _l(mLock);
  5. mDispatcherIsAliveCondition.broadcast();
  6. // Run a dispatch loop if there are no pending commands.
  7. // The dispatch loop might enqueue commands to run afterwards.
  8. if (!haveCommandsLocked()) {           //如果有缓存的命令就调用下面的runCommand去执行,没有的话这里去检查是否有新的input事件,这里定义一个唤醒时间控制
  9. dispatchOnceInnerLocked(&nextWakeupTime);
  10. }
  11. // Run all pending commands if there are any.
  12. // If any commands were run then force the next poll to wake up immediately.
  13. if (runCommandsLockedInterruptible()) {
  14. nextWakeupTime = LONG_LONG_MIN;
  15. }
  16. } // release lock
  17. // Wait for callback or timeout or wake.  (make sure we round up, not down)
  18. nsecs_t currentTime = now();
  19. int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
  20. mLooper->pollOnce(timeoutMillis);  //执行上面一次分发之后,就进入了loop,这个loop会持续的检测对应的管道中是否有内容可读,而另外一个线程InputReader 读取到input事件之后就会往这个管道写入
  21. }

这个是处理input事件的,后续分析,先看怎么读取事件.

InputReader读取:

源码位于frameworks/base/libs/ui/InputReader.cpp ,开启线程如下:

[objc] view plain copy
  1. bool InputReaderThread::threadLoop() {
  2. mReader->loopOnce();
  3. return true;
  4. }

这里看这个loopOnce:

[objc] view plain copy
  1. void InputReader::loopOnce() {
  2. ...
  3. size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);  //这里去获取event事件
  4. ...
  5. if (count) {
  6. processEventsLocked(mEventBuffer, count); //如果获取到事件,就处理
  7. }
  8. ...
  9. }

可以看到这里就到了获取event事件了。上一篇中有提到!

getEvent中会一直read,直到get到event之后,通过precessevent处理,最终会唤醒上面介绍到的InputDispatcherThread,通知它有新的事件来了

Linux/Android——Input系统之frameworks层InputManagerService (六)【转】相关推荐

  1. Android input 系统InputReader,InputDispatcher线程实例--UI死掉

    Android input 系统InputReader,InputDispatcher线程实例–UI死掉但touch 正常报点 依据 Android input 系统初始化和启动流程中的背景: 做An ...

  2. 【Android】带你细看Android input系统中ANR的机制

    "本文基于Android13源码,分析Input系统的Anr实现原理" 在文章之前,先提几个问题: 如果在activity任意周期(onCreate,onResume等),同步执行 ...

  3. [Android Input系统]MotionEvent的序列化传送

    这里从云游戏的触控操作看起, PC端的客户端支持按键和鼠标滑动操作,手机上的云游戏客户端则是和手机游戏一样的touch触控,客户端的touch操作是怎样处理给服务端的呢,猜测是把touch操作&quo ...

  4. Android Input系统之触摸屏

    2019独角兽企业重金招聘Python工程师标准>>> 最近开始在TI平台调试触摸屏,之前研究过Android的Event输入设备驱动,对键盘比较了解.Input驱动程序包含游戏杆. ...

  5. Linux/Android——input_handler之evdev (四)

    在前文 Linux/Android--input子系统核心 (三)中概括了总体的结构,以及介绍了input核心的职责,其中有说道注册input设备时会去匹配已有的事件处理器handler, 而这个ha ...

  6. android log系统

    转载自http://blog.csdn.net/Luoshengyang/article/category/838604/3 Android系统开发中LOG的使用 在程序开发过程中,LOG是广泛使用的 ...

  7. android mtk 系统架构,Android振动器(Vibrator)系统详解

    平台 MTK6573 Android 振动器系统架构 驱动层 硬件抽象层 JNI框架层 Java应用层 一.驱动层 Android修改.新增Linux内核文件 /kernel/drivers/stag ...

  8. AOSP源码分析:Android Input事件的产生、读取和分发

    大家好,今天为大家推荐来自MIUI的Cheeeelok同学的AOSP源码分析系列文章,本文依然从源码的角度带大家理解Android Input事件的产生.读取和分发.还没有看过作者上一篇文章 Andr ...

  9. linux编译避免污染源码分离,如何避免linux上的系统标准C/C++库?

    我安装了新版本的GCC,这对我的linux系统造成了污染.我计划以更好的方式处理多个版本的GCC.我计划在/ opt / tools目录下安装所有不同的版本.然后我的项目makefile显式指定要使用 ...

最新文章

  1. 在SCSS文件中导入常规CSS文件?
  2. hihocoder#1054 : 滑动解锁(深度优先搜索)
  3. 苹果手机视频传输教程-通过无线将电脑上视频传到手机
  4. android context.java_Android / Java类范围和Context
  5. MySQL高级 - 案例 - 系统性能优化 - 分页优化
  6. 你知道吗…我不知道…你知道吗
  7. Jsp页面用javascript加 滑动验证条
  8. 中常用的函数_ST语言编程中常用的函数/功能块
  9. 商品二因素、劳动二重性
  10. list vue 添加数据方法_在PySpark数据框中添加新列的5种方法
  11. vue for 初始值_vue全套教程(实操)就在这里
  12. 2018第九届蓝桥杯JavaB组省赛真题详解
  13. unity3d学习笔记-动画(1.Unity 中动画的基本原理)
  14. uniapp跨域设置
  15. 分体式降噪耳机有哪些?高配置分体式降噪耳机排行榜
  16. Nessus介绍与安装
  17. 【CTF】Misc7——乌云邀请码+图穷匕见+convert
  18. python中类的首字母一定得大写吗_Python学习
  19. Android 媒体播放框架MediaSession分析与实践
  20. Google Capture The Flag 2019 (Quals) WP

热门文章

  1. zeit_Zeit风格的Vue实现
  2. C++ 中头文件(.h)和源文件(.cc)的写法简述
  3. ps2019最新版-安装地址
  4. 企业网站建设与UI设计的关系
  5. 文心一言:这48小时,我被问了xxxx个问题
  6. java querystring_Java URL encoding of query string parameters
  7. LWN:机器学习模型的偏见和伦理问题
  8. 图像视图ImageView:图像拉伸演示
  9. 适合做app的前端框架有哪些?webAPP移动端App:react native、weex、flutter
  10. Linux安装minigui教程,MiniGui开发:Ubuntu14.04环境安装qvfb工具