Android事件传递
来源:互联网 发布:淘宝网开店流程 编辑:程序博客网 时间:2024/06/03 20:15
1. 在Activity的启动过程中,窗口和视图创建完后, 会创建输入通道InPutChannel, 该类执行了Parceladble,专门用来传输用户输入事件给window.
2. 用InPutChannel和主线程的Looper作为参数创建事件接收器WindowInputEventReceiver.
mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,Looper.myLooper());
WindowInputEventReceiver继承InputEventReceiver,是ViewRootImpl的内部类.
3. 当native层的输入管理器监听到输入事件后调用InputEventReceiver.dispatchInputEvent()方法,该方法再通过以下调用链最终进入DecorView.dispatchKeyEvent()方法执行.
WindowInputEventReceiver.onInputEvent()—>enqueueInputEvent()—>doProcessInputEvents()—>deliverInputEvent()—>deliver()—>
ViewPostImeInputStage.onProcess()—>ViewPostImeInputStage.processKeyEvent()—>DecorView.dispatchKeyEvent()
4. DecorView.dispatchKeyEvent()方法有两个分支:
1) 在窗口被销毁的时候,比如息屏状态下调整音量,则直接调用PhoneWindow.onKeyDown()方法,并在该方法中处理音量的调节.
2) 在窗口没有被销毁的时候,调用Activity.dispatchKeyEvent()方法进行事件分发.
public boolean dispatchKeyEvent(KeyEvent event) { final int keyCode = event.getKeyCode(); final int action = event.getAction(); final boolean isDown = action == KeyEvent.ACTION_DOWN; ... if (!isDestroyed()) { //窗口没有销毁的情况 final Callback cb = getCallback(); final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event) //这个Callback是在activity的attach()方法里面设置到window中的。 : super.dispatchKeyEvent(event); if (handled) { return true; } } return isDown ? PhoneWindow.this.onKeyDown(mFeatureId, event.getKeyCode(), event) //窗口销毁后直接调用PhoneWindow的onkeyDown()方法处理。 : PhoneWindow.this.onKeyUp(mFeatureId, event.getKeyCode(), event); }5. Activity通过PhoneWindow将事件传递给view系统
public boolean dispatchKeyEvent(KeyEvent event) { onUserInteraction(); // Let action bars open menus in response to the menu key prioritized over // the window handling it if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && //按的menu键,则直接调用mActionBar.onMenuKeyEvent(event),并返回true,事件不再向下传递。 mActionBar != null && mActionBar.onMenuKeyEvent(event)) { return true; } Window win = getWindow(); if (win.superDispatchKeyEvent(event)) { //通过PhoneWindow调用view和viewgrounp的Dispatch方法传递事件,如果该事件被某个view或者viewgrounp处理, // 返回true,到此结束,否则继续向下传递。 return true; } View decor = mDecor; if (decor == null) decor = win.getDecorView(); return event.dispatch(this, decor != null ? decor.getKeyDispatcherState() : null, this); //如果该事件没有被view或者viewgrounp处理,则直接调用event.dispatch(),
//在该方法里面调用activiy的onkeydown()方法处理。 }6. view系统将事件从根view开始向子view传递,如果事件被某个view或者viewGrounp消费,则停止向下传递,否则最终将调用Activity的onKeyDown()方法进行处理.
以textView为例,事件在view系统的传递路径为:
DecorView.superDispatchKeyEvent()—>viewgrounp.dispatchKeyEvent()—>view.dispatchKeyEvent()—>KeyEvent.dispatch()—>TextView.onKeyDown()
- android 事件传递机制
- android 事件传递机制
- android触摸事件传递
- android事件传递机制
- android 事件传递
- Android触摸事件传递
- Android事件传递机制
- Android 事件传递机制
- android 事件的传递
- Android事件传递机制
- Android中的事件传递
- Android事件传递机制
- Android事件传递机制
- Android事件传递机制
- Android事件传递机制
- Android事件传递机制
- Android事件传递机制
- android touch事件传递
- PHP7 与 PHP5 foreach 函数的区别 详解
- 阿里天池大赛实战记录之菜鸟-需求预测与分仓规划
- Struts2_Spring_Hibernate整合及测试_3(标准)
- 队列模板
- 343. Integer Break
- Android事件传递
- 初识网络编程
- sublime好看的字体设置
- java多线程之synchornized原理以及原子操作探究学习
- Linux系统调用列表(四)用户管理
- 一种BootLoader的分析说明
- 设计模式—观察者模式(十)
- BZOJ2982: combination
- 集训DAY1 机房测试(贪心,图论)