点击事件是如何传递给Activity的
2016-05-10 15:01
447 查看
事件从Window传递给Activity,在windowgloble的addview方法中会创建InputChannel、InputQueue和WindowInputEventReceiver来接受点击事件的消息。
ViewRootImpl中有个方法
我们看是如何被处理的
会调用doProcessInputEvents方法
在ViewRootImpl中,有一系列类似于InputStage(输入事件舞台)的概念,每种InputStage可以处理一定的事件类型,比如AsyncInputStage、ViewPreImeInputStage、ViewPostImeInputStage等。当一个InputEvent到来时,ViewRootImpl会寻找合适它的InputStage来处理。对于点击事件来说,ViewPostImeInputStage可以处理它,ViewPostImeInputStage中,有一个processPointerEvent方法,如下,它会调用mView的dispatchPointerEvent方法,注意,这里的mView其实就是DecorView。
我们看View中的dispatchPointerEvent,因为DecorView继承自View
然后调用了DecorView的dispatchTouchEvent
这里的cb就是Activity对象。
ViewRootImpl中有个方法
private void scheduleProcessInputEvents() { if (!mProcessInputEventsScheduled) { mProcessInputEventsScheduled = true; Message msg = mHandler.obtainMessage(MSG_PROCESS_INPUT_EVENTS); msg.setAsynchronous(true); mHandler.sendMessage(msg); } }
我们看是如何被处理的
case MSG_PROCESS_INPUT_EVENTS: mProcessInputEventsScheduled = false; doProcessInputEvents(); break;
会调用doProcessInputEvents方法
void doProcessInputEvents() { // Deliver all pending input events in the queue. while (mPendingInputEventHead != null) { QueuedInputEvent q = mPendingInputEventHead; mPendingInputEventHead = q.mNext; if (mPendingInputEventHead == null) { mPendingInputEventTail = null; } q.mNext = null; mPendingInputEventCount -= 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, mPendingInputEventCount); deliverInputEvent(q); }
private void deliverInputEvent(QueuedInputEvent q) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, "deliverInputEvent"); try { if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0); } InputStage stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage; if (stage != null) { stage.deliver(q); } else { finishInputEvent(q); } } finally { Trace.traceEnd(Trace.TRACE_TAG_VIEW); } }
在ViewRootImpl中,有一系列类似于InputStage(输入事件舞台)的概念,每种InputStage可以处理一定的事件类型,比如AsyncInputStage、ViewPreImeInputStage、ViewPostImeInputStage等。当一个InputEvent到来时,ViewRootImpl会寻找合适它的InputStage来处理。对于点击事件来说,ViewPostImeInputStage可以处理它,ViewPostImeInputStage中,有一个processPointerEvent方法,如下,它会调用mView的dispatchPointerEvent方法,注意,这里的mView其实就是DecorView。
private int processPointerEvent(QueuedInputEvent q) { final MotionEvent event = (MotionEvent)q.mEvent; // Translate the pointer event for compatibility, if needed. if (mTranslator != null) { mTranslator.translateEventInScreenToAppWindow(event); } // Enter touch mode on down or scroll. final int action = event.getAction(); if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_SCROLL) { ensureTouchMode(true); } // Offset the scroll position. if (mCurScrollY != 0) { event.offsetLocation(0, mCurScrollY); } // Remember the touch position for possible drag-initiation. if (event.isTouchEvent()) { mLastTouchPoint.x = event.getRawX(); mLastTouchPoint.y = event.getRawY(); } return FORWARD; }
我们看View中的dispatchPointerEvent,因为DecorView继承自View
public final boolean dispatchPointerEvent(MotionEvent event) { if (event.isTouchEvent()) { return dispatchTouchEvent(event); } else { return dispatchGenericMotionEvent(event); } }
然后调用了DecorView的dispatchTouchEvent
@Override public boolean dispatchTouchEvent(MotionEvent ev) { final Callback cb = getCallback(); return cb != null && !isDestroyed() && mFeatureId < 0 ? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev); }
这里的cb就是Activity对象。
相关文章推荐
- Solr之搭建Solr5.2.1服务并从Mysql上导入数据
- AFNetworking报错"_UTTypeCopyPreferredTagWithClass", referenced from: _AFContentTypeForPathExtens
- SQL Server T-SQL高级查询
- Android笔记 httpurlconnection
- 第十一周补充程序-1-春哥
- MassTransit 学习记录(杂项) IConsumer泛型实现和多继承
- UISwitch用法:
- Laravel Breadcrumbs 自动面包屑导航
- MAC下SVN 命令的使用
- 用java写多位数乘法
- rose 软件安装程序
- NTFS Journaling
- 自定义下拉刷新和上拉加载的recycleview
- 微信支付
- 工业设备IP等级
- centos上传下载文件
- 24位RGB数据保存为BMP图片
- red5源码分析---8
- android分辨率适配
- 勿忘初心 不负梦想