一、KeyEvent传递过程
主要可以划分为三步:过滤器、View树、Activity。
1.WindowManagerService.java内有两个线程,一个负责分发按键消息,一个负责读取按键消息。在执行processEvent分发事件时,系统有一些过滤器可以进行一些特定的处理操作,这些过滤器的处理既可以在事件分发前也可以在事件分发后。比如home键在分发前进行处理消费,应用无法监听该类消息,而返回键是在事件分发之后,只有当应用不进行处理时,系统才会处理返回键用来退出当前Activity,。
2.processEvent分发事件后,先传递到ViewRootImpl的deliverKeyEvent中,如果mView(即根DecorView)为空或者mAdded为false,则直接返回。若不为空,然后判断IME窗口(输入法)是否存在,若存在则优先传递到IME中,当输入窗口没有处理这个事件,事件则会真正派发到根视图mView.dispatchKeyEvent中,然后回调Activity的dispatchKeyEvent(event)去处理,由于Activity中的dispatchKeyEvent最终调用的是mDecor中的superDispatchKeyEvent(event),之后就是ViewGroup通过递归调用把Event传递到指定的View上。
3.事件传递到VIew之后,先会调用View的dispatchKeyEvent,如果有注册Listener,就直接调用Listener的onKey去响应,如果没有注册Listener,z之后会根据Action的类型调用对应的onXXX(onKeyDown,onKeyup)函数去处理,如果所有的view都没有进行处理,那么最终会回调到activity的onXXX方法中。
二、Activity View的dispatchKeyEvent,onkeyDown,onKeyUp, setListener处理顺序
1. Activity.dispatchKeyEvent(down) ----->view.dispatchKeyEvent ------>view.setListener(如setOnKeyListener) ------>view.onkeyDown------->Activity.onkeyDown------>Activity.dispatchKeyEven(up)------>view.dispatchKeyEvent---->view.setListener(如setOnKeyListener) ------>view.onkeyup----->view.onClick(setOnClickListener)---->Activity.onkeyUp
2. 当一个event事件传递到某个view上时,如果对一些Action(比如Down)进行了消费后,则该View下的子view以及想消费该event的Action的行为都不会执行。默认情况下,ViewGroup控件不会执行onkeyDown和onkeyup,只有当其焦点属性为true时,才可以传递到执行