android中的按键处理
16lz
2021-01-24
转载自
http://venus585625.iteye.com/blog/907740
写的不错,比较深入,转贴于此
在android中,所有的按键、触屏等事件,都是从顶至下进行分发的。每个ViewGroup子类对象会维持一个Focused变量。它表示在这个控件中具有Focused控件(此控件或是其子控件)。当有按键发生时 会沿着Focuse Path 找到RealFocus 控件(是真正Focused 控件,不是其子控件具有焦点)。同理触屏事件的分发也是如此,只不过和Focuse无关。父控件会遍历所有子控件,看看谁处于触碰事件,并分发给它。
如果Home key、Menu key,Back Key,Enter key事件(或许还有别的按键)(一些特殊功能的按键,声音等等)发生时 ,会产生一个FINISHED_EVENT 消息,是由InPutMethodManagerService通过AIDL进程调用产生 。
在ViewRoot 中捕获。
- caseFINISHED_EVENT:
- handleFinishedEvent(msg.arg1,msg.arg2!=0);
- break;
- dhandleFinishedEvent(intseq,booleanhandled){
- finalKeyEventevent=(KeyEvent)retrievePendingEvent(seq);
- if(DEBUG_IMF)Log.v(TAG,"IMEfinishedevent:seq="+seq
- +"handled="+handled+"event="+event);
- if(event!=null){
- finalbooleansendDone=seq>=0;
- if(!handled){
- deliverKeyEventToViewHierarchy(event,sendDone);
- return;
- }elseif(sendDone){
- if(LOCAL_LOGV)Log.v(
- "ViewRoot","Tellingwindowmanagerkeyisfinished");
- try{
- sWindowSession.finishKey(mWindow);
- }catch(RemoteExceptione){
- }
- }else{
- Log.w("ViewRoot","handleFinishedEvent(seq="+seq
- +"handled="+handled+"ev="+event
- +")neitherdeliveringnorfinishingkey");
- }
- }
普通按键 发生时,产生DISPATCH_KEY_FROM_IME 消息 由ViewRoot捕获此消息
Java代码
- caseDISPATCH_KEY_FROM_IME:{
- if(LOCAL_LOGV)Log.v(
- "ViewRoot","Dispatchingkey"
- +msg.obj+"fromIMEto"+mView);
- KeyEventevent=(KeyEvent)msg.obj;
- if((event.getFlags()&KeyEvent.FLAG_FROM_SYSTEM)!=0){
- //TheIMEistryingtosaythiseventisfromthe
- //system!Badbadbad!
- event=KeyEvent.changeFlags(event,
- event.getFlags()&~KeyEvent.FLAG_FROM_SYSTEM);
- }
- deliverKeyEventToViewHierarchy((KeyEvent)msg.obj,false);
- }break;
上面两大类按键如果预先没有别处理,都会由deliverKeyEventToViewHierarchy(event, sendDone);进行分发。
分发路径:PhoneWindow.DecorView dispatchKeyEvent----》Activity dispatchKeyEvent ----》Window superDispatchKeyEvent --->DecorView superDispatchKeyEvent-->Super dispatchKeyEvent,后续按着 Focus Path分发。如果上述分发中未被处理
会执行Activity dispatchKeyEvent 中的如下代码:
Java代码
- event.dispatch(this,decor!=null
- ?decor.getKeyDispatcherState():null,this);
进一步调用Focus Path中的 View 的 onXXX方法。如果在这些回调方法中,按键未被处理,则进一步由 PhoneWindow.DecorView中dispatchKeyEvent方法的代码
Java代码
- returnisDown?PhoneWindow.this.onKeyDown(mFeatureId,event.getKeyCode(),event)
- :PhoneWindow.this.onKeyUp(mFeatureId,event.getKeyCode(),event);
处理了:volumn key ,back key 等等按键。
了解了这些就可以游刃有余地截获按键事件。。
“Home key”如果应用程序中没有截获,则最后调用 Activity 中的onBackPressed
默认实现:
Java代码
- /**
- *Calledwhentheactivityhasdetectedtheuser'spressoftheback
- *key.Thedefaultimplementationsimplyfinishesthecurrentactivity,
- *butyoucanoverridethistodowhateveryouwant.
- */
- publicvoidonBackPressed(){
- finish();
- }
更多相关文章
- 写一个Android输入法01——最简步骤
- Delphi XE5 for Android(安卓)(十)
- android GPS开启方法 代码
- Android中的悬浮对话框和即点即关对话框
- android 一个有漂亮动画效果的Dialog
- 通用代码库之listview和GridView
- android 4.4 禁止使用power键的休眠功能
- android中在java代码中设置Button按钮的背景颜色
- Android获取手机号码和运营商信息的方法