Android 4.0按键事件以及系统流程分析
Android 4.0中按键的处理流程
按键在Android系统中,有着不同的代表意义。以前的全键盘的手机代码没有阅读过,所以也不是很了解。本人介绍的是在触摸屏的手机上的按键消息的处理流程。
在现在触摸屏成为主流的输入设备的情况下,很多厂商都在努力的做到取消物理按键的工作,但是目前就本人的学习情况来看,完全取消在目前看来还是不是那么现实。
有如下几点原因:
首先,本人说明的是目前原生的Android系统上。
其次,Android系统为了节省电量,在电源管理的过程中设置了休眠的方式。而休眠的时候触摸屏同样进入休眠状态。因此,不能够接收到用户的输入消息。
再次,目前的物理按键(主要指power,volume。home)是通过电源管理芯片进行控制的。触摸屏不是。
因此,如果没有现在的物理按键的情况下,如果想把设备从休眠的状态下唤醒基本上来讲是不可能的。
下面来正式的记录下本人在学习的过程中记录的点点滴滴。
首先,简要的介绍一下按键的处理流程。先简单的分为两大类:一类是虚拟按键。另一类是物理按键。
无论是虚拟按键还是物理按键都是要经过驱动层注册为输入设备,然后上报到kernel/drivers/input/input.c中。这里有相关函数的定义。然后通过、sys上报到frameworks/services/input/EventHub.cpp中,在这里会对设备进行扫描并且判断是哪种设备,然后在InputReader.cpp中对原始数据进行读取。在framewoks/services/input/InputDispatcher.cpp中实现数据的派发。在framework/base/core/jni/android_view_KeyEvent.cpp中实现通过JNI机制向上层的KeyEvent.java提供数据。并且在frameworks/base/core/java/android/view/KeyEvent.java中向上层的APP开发人员提供接口。
当然,虚拟键盘中有一个映射关系,键盘的按键值也会上报给上面的应用层,而对于物理按键往往是在frameworks层就被截取并且加以处理了。
普通的按键事件在Android系统中的调用流程(本人不太会处理visio绘图的保存问题)大致如下:
下图是人家goole的图 是比俺画的好啊……
但是对于物理按键的处理流程,目前主要查阅的代码的结果是在PhoneWindowManager.java中进行截获并处理的。
Android 4.0按键事件以及电源管理流程分析
Android是集成了linux内核以及frameworks层的东西而形成为os,其中主要包含了三种语言的编程,主要是c、c++以及java。因此他们之间的通信问题就显得尤为突出。
JAVA与c的通讯主要是通过JNI机制进行的。为了提高效率,在上层都使用java进行编程。因此在阅读源代码的过程中,就需要区分给用户使用的文件,系统内部使用的文件,以及与驱动打交道的文件。
Android获取系统消息概述
1、获取原始的用户消息,包括按键、触摸屏、鼠标、轨迹球等各种输入设备的消息。
2、对原始消息进行一定的加工,使之转化为程序可以理解的消息。比如所有的按键消息都包括“按下、弹起”等原始消息,而对程序来讲可能只关心该按键被“按了一次”或者“长按”,因此需要把原始消息转换为程序可以理解的消息。
3、把转换后的消息发送到相应的用户窗口所在的进程。如果获取线程和用户线程同在一个进程空间中,则传递消息比较简单,但对于多进程系统来讲,消息获取线程和用户线程往往在不同的进程空间中,因此需要使用IPC机制把消息传递到用户窗口所在的线程中。
在接下来的几篇博文中将陆续写如下内容:
WindowManagerService处理消息的时机
上报和分发的消息的处理流程
AIDL简介
WindowManagerService处理消息的时机
目前对于用户的输入消息分析的文章大都是划分为两种类型,一种是key消息,另一种是motion消息。
对于motion消息,Android原生系统中对其处理都是直接上报的。WindowManagerService没有对其做过多的处理。而对于key消息,则会首先回调WmS中的Key消息处理函数,在WindowManagerService中不处理该消息时才把消息发往客户窗口中。在一般情况下,WindowManagerService中仅处理一些系统Key消息,比如“HOME”键、照相按键、声音按键等。
在WindowManagerService中注册服务通道时,调用了Java环境中的InputManager对象mInputManager,而该类的构造函数中创建了一个callbacks变量,然后再nativeInit(mCallbacks)进行了初始化。变量mCallbacks作为初始化的参数传递到native环境中的InputManager对象中,从而使得在InputDispatcher进行回调时首先回调到Java环境中的InputManager.callbacks子类中。比如Callbacks中包含了interceptKeyBeforeDispatching()函数,当InputDispatcher()接收到Key消息时,首先回调该函数,而该函数的内部代码中,又调用了WindowManagerService对象中的InputMonitor的同名函数。
AIDL简介
通常每个应用程序都在他自己的进程内运行,但有时需要在进程之间传递对象(IPC通信)。此时可以通过应用程序UI的方式写一个运行在不同进程中的service。在Android平台中,一个进程通常不能访问其他进程中的内存区域。所以它们需要把对象拆分成操作系统能理解的简单形式,以便伪装成对象跨边界访问。而要完成这些需要AIDL机制。
AIDL(Android接口描述语言)是一个IDL语言,它可以生成一段代码,可以是一个在Android设备上运行的两个进程使用内部通信进程进行交互。如果你想在一个进程中(例如在一个Activity中)访问另一个进程中(例如service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。
要使用AIDL,service需要以AIDL文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务器接口中包含一个功能调用的stub()服务桩类。service的onBind方法会返回实现类的对象,之后你就可以使用它了。
AIDL文件
framework中包含的aidl是在frameworks/base/Android.mk中定义的。该文件定义了两处aidl文件列表。
第一处是给LOCAL_SRC_FILES变量中使用 “+=” 进行赋值,该变量将包含在framework.jar目标中的所有源文件,包括aidl文件和java文件。
第二处是给aidl_files变量使用“:=”赋值符号进行赋值,该变量仅仅包含android.jar目标中所有的aidl文件。
因此,当给Frameworks中添加新的aidl文件时,需要考虑文件是否要公开到SDK中。如果需要,则需要把该文件路径同时添加到以上两个变量中;如果不需要公开到SDK中,则只需要把文件路径添加到LOCAL_SRC_FILES变量中。
在完成这些操作后编译仍会出现问题,此时需要运行,make update-api命令,此时改变的文件是current.txt改变的内容如下:
+ public abstract interface IEneaService implements android.os.IInterface {
+ }
+
+ public static abstract class IEneaService.Stub extends android.os.Binder implements android.os.IEneaService {
+ ctor public IEneaService.Stub();
+ method public android.os.IBinder asBinder();
+ method public static android.os.IEneaService asInterface(android.os.IBinder);
+ method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;
+ }
+
这时,如果希望在写的Activity中使用的情况下,需要首先获取服务,这个步骤是通过"ServiceManager.getService()"这个API实现。然后使用service handle来调用service暴露出来的函数。ITestService om = ITestService.Stub.asInterface(ServiceManager.getService("Test"));
下面是个简单的例子:
/* * HelloServer.java */ package com.Test.helloserver; import android.app.Activity; import android.os.Bundle; import android.os.ServiceManager; import android.os.ITestService; import android.util.Log; public class HelloServer extends Activity { private static final String DTAG = "HelloServer"; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ITestService om = ITestService.Stub.asInterface(ServiceManager.getService("Test")); try { Log.d(DTAG, "Going to call service"); om.setValue(20); Log.d(DTAG, "Service called succesfully"); } catch (Exception e) { Log.d(DTAG, "FAILED to call service"); e.printStackTrace(); } } }
上报和分发消息的流程
概论
Android 4.0按键事件以及系统流程分析相关推荐
- Android 5.0(Lollipop)事件输入系统(Input System)
其实Android 5.0中事件输入子系统的框架和流程没有本质变化.Service端的实现在/frameworks/native/services/inputflinger/下(4.4中在/frame ...
- 华为内测基于Android 10.0的EMUI 10系统;2019年Q1真无线耳机市场份额,苹果占半壁江山……...
关注并标星星CSDN云计算 极客头条:速递.最新.绝对有料.这里有企业新动.这里有业界要闻,打起十二分精神,紧跟fashion你可以的! 每周三次,打卡即read 更快.更全了解泛云圈精彩news g ...
- 一加3t氢android8_一加3t氢android8_一加氢OS推出Android 8.0正式版 新系统流畅到飞起...
原标题:一加氢OS推出Android 8.0正式版 新系统流畅到飞起 一加手机早在去年万圣节就在一加3和3T上开始公测基于Android 8.0的氢系统了,但奈何当时由于国内大部分软件都不兼容而导致迟 ...
- 一加3t氢android8_一加氢OS推出Android 8.0正式版 新系统流畅到飞起
原标题:一加氢OS推出Android 8.0正式版 新系统流畅到飞起 一加手机早在去年万圣节就在一加3和3T上开始公测基于Android 8.0的氢系统了,但奈何当时由于国内大部分软件都不兼容而导致迟 ...
- 高通Android智能平台环境搭建_编译流程分析
高通Android智能平台环境搭建_编译流程分析 高通平台环境搭建,编译,系统引导流程分析 TOC \o \h \z \u 1. 高通平台android开发总结. 7 1.1 搭建高通平台环境开发环境 ...
- Android6.0 Reset恢复出厂设置流程分析
点击Settings应用中的恢复出厂设置按钮后流程分析: 先使用grep命令搜索"恢复出厂设置"字符串,找到相应的布局文件: packages/apps/Settings/res/ ...
- 【高通SDM660平台 Android 10.0】(12) --- Camera Chromatix 代码分析
[高通SDM660平台 Android 10.0]Qcom Camera Daemon 代码分析 一.chromatix_imx258_lc898217xc 目录 1.1 例:imx258_lc898 ...
- Android平台开发-Android keypad map-Android按键事件
http://hi.baidu.com/i_know_all/blog/item/0a1dd8ecdde99acb2f2e2159.html 一.Android底层按键事件处理过程 在系统启动后,在文 ...
- Android强行进阶—按键事件焦点事件攻略
前言 对于Android手机APP普通开发者来说,KeyEvent接触相对较少,相反接触较多的应该是TouchEvent.而Android TV开发者对KeyEvent的接触就非常频繁.这也是手机应用 ...
最新文章
- php中网页加入音乐,PHP网站插入音乐
- Basic Sorting Algorithms
- centos下redis安装
- java查询到更新之前的数据_Java对数据库的查询和更新操作详解
- 《Android应用开发揭秘》读者问题汇总
- 错误调试:Ubuntu-Tensorflow ,程序手动结束后,GPU的显存没有被释放
- MySQL8.0忘记密码了如何修改密码
- bzoj 4871: [Shoi2017]摧毁“树状图” [树形DP]
- window多个oracle查版本,Oracle SQL多版本VERSION_COUNT产生的可能性
- html视频直播源码,用HTML5开发简单的视频播放器,附源码
- 模拟器游戏修改之教你如何修改gba rom里的程序!
- NPDP知识推送-第三章新产品开发流程管理(1)
- ios linux远程控制软件,ios手机远程控制 ToDesk 1.0.9 iOS/iPad 版下载(远程控制软件)-520下载...
- matlab中水平垂直线,关于Matlab:水平-垂直线
- 教学案例六 多重循环
- C语言中使用rand()函数产生随机数用法
- 解决Maven打包报错:Failed to clean project: Failed to delete
- 荣联再次中标中国移动云资源池项目
- [面经整理] 机器/深度学习补充篇
- windows 远程连接 快捷键
热门文章
- Grafana 设置 Right Y
- 跨域请求实现百度搜索和360搜索的智能提示
- java爬虫爬取互联网上的各大影视网站---360影视(附源码下载)
- mount error(112): Host is down
- 基于C++的中国行政区域图染色与信息查询 课程论文+任务书+代码
- EMC测试项及解决方案
- 计算机word2003操作试题,职称计算机word2003操作试题
- wm_concat函数用法
- wap.php区别,WAP与PHP程序设计之基础篇
- 【恒指早盘分析】9.11恒指今日总结及后市思路