地址:承德市南平路940号
电话:13954072965
传真:13732592923
邮箱:414913562@qq.com
我们知道Android系统的按键分为三类:(1)Global Key;(2)System Key;(3)User Key
Global Key:按下一个按键,启动某个APP。 具体使用哪个按键启动哪个APP可以自己指定,修改\frameworks\base\core\res\res\xml\Global_keys.xml,接下来有一篇博文具实现,假设它是AKEYCODE_TV
System Key:比如音量键(AKEYCODE_VOLUME_DOWN)
User Key:其他按键,比如ABCD(AKEYCODE_A)
Reader线程把驱动上报的scancode根据.kl文件转化为keycode,Dispatch线程根据所获得keycode进行处理。Android Dispatch线程对这三类按键的处理
* Global Key
* System Key
* User Key
之前已经分析了Reader线程从驱动程序得到扫描码之后,根据.KL文件,得到对应的按键码,然后构造args参数,接着使用NotifiyKey将该参数告诉Reader线程的Listener,而Reader线程的监听者肯定为Dispatch线程,要想验证,可以通过源代码分析得出。
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2.1 调用Java里面PhoneWindowManager的同名函数
2.2 根据返回值设置policeFlags,对于global按键直接返回Pass_To_User
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
needWake = enqueueInboundEventLocked(newEntry);
if (needWake) {
mLooper->wake();
}
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2.1 调用Java里面PhoneWindowManager的同名函数,分类处理
可以处理的紧急事件,处理他,设置返回值为:!Pass_to_user
返回pass_to_user
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
needWake = enqueueInboundEventLocked(newEntry);
if (needWake) {
mLooper->wake();
}
NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
getListener()->notifyKey(&args);
}
2.1 调用Java里面PhoneWindowManager的同名函数
2.2 根据返回值设置policyFlags,对于用户按键直接返回Pass_To_User
//policyFlasgs接收函数的输出结果,根据policyFlags构造newEntry,将newEntry放入队列中
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
needWake = enqueueInboundEventLocked(newEntry);
if (needWake) {
mLooper->wake();
}
从上文分析可知,不论是否Pass_to_user,最终都要放入到队列mInboundQueue当中去,上篇博客总结的流程图有点错误,故进行修改,具体如下图。
地址:兰州市襄樊路754号
电话:13664060358
传真:15862786043
邮箱:3211596@qq.com
0.1339