当前位置: 首页 > news >正文

seo站内站怎么做牛栏前网站建设

seo站内站怎么做,牛栏前网站建设,可信的免费网站建设,私人做网站要多少钱在Android 11 输入系统之InputDispatcher和应用窗口建立联系一文中介绍到#xff0c;当InputDispatcher写入数据后#xff0c;客户端这边就会调用handleEvent方法接收数据 //frameworks\base\core\jni\android_view_InputEventReceiver.cpp int NativeInputEventReceiver::h…在Android 11 输入系统之InputDispatcher和应用窗口建立联系一文中介绍到当InputDispatcher写入数据后客户端这边就会调用handleEvent方法接收数据 //frameworks\base\core\jni\android_view_InputEventReceiver.cpp int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {//省略if (events ALOOPER_EVENT_INPUT) {//之前构造数据的时候events为ALOOPER_EVENT_INPUTJNIEnv* env AndroidRuntime::getJNIEnv();status_t status consumeEvents(env, false /*consumeBatches*/, -1, nullptr);mMessageQueue-raiseAndClearException(env, handleReceiveCallback);return status OK || status NO_MEMORY ? 1 : 0;}//省略继续调用consumeEvents处理 //frameworks\base\core\jni\android_view_InputEventReceiver.cpp status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {//省略for (;;) {uint32_t seq;InputEvent* inputEvent;status_t status mInputConsumer.consume(mInputEventFactory,consumeBatches, frameTime, seq, inputEvent);//1//省略case AINPUT_EVENT_TYPE_MOTION: {MotionEvent* motionEvent static_castMotionEvent*(inputEvent);//使用inputEvent构造MotionEvent对象if ((motionEvent-getAction() AMOTION_EVENT_ACTION_MOVE) outConsumedBatch) {*outConsumedBatch true;}inputEventObj android_view_MotionEvent_obtainAsCopy(env, motionEvent);//创建java层的MotionEvent对象并将该对象的mNativePtr指向c的MotionEvent对象break;}//省略env-CallVoidMethod(receiverObj.get(),gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);//2//省略 }注释1处接收InputDispatcher发过来的数据并将数据封装成InputEvent对象注释2处通过JNI调用InputEventReceiver的dispatchInputEvent方法 先来看一下如何接收数据的 //frameworks\native\libs\input\InputTransport.cpp status_t InputConsumer::consume(InputEventFactoryInterface* factory, bool consumeBatches,nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {//省略while (!*outEvent) {if (mMsgDeferred) {// mMsg contains a valid input message from the previous call to consume// that has not yet been processed.mMsgDeferred false;} else {// Receive a fresh message.status_t result mChannel-receiveMessage(mMsg);//1//省略switch (mMsg.header.type) {case InputMessage::Type::MOTION: {//省略MotionEvent* motionEvent factory-createMotionEvent();if (!motionEvent) return NO_MEMORY;updateTouchState(mMsg);initializeMotionEvent(motionEvent, mMsg);//2*outSeq mMsg.body.motion.seq;*outEvent motionEvent;//省略break;}}注释1处接收数据接收到的数据是InputMessage对象。注释2处根据读取到的InputMessage创建motionEvent对象 //frameworks\native\libs\input\InputTransport.cpp status_t InputChannel::receiveMessage(InputMessage* msg) {ssize_t nRead;do {nRead ::recv(mFd.get(), msg, sizeof(InputMessage), MSG_DONTWAIT);//读fd} while (nRead -1 errno EINTR);consume方法得到数据并将数据封装成motionEvent对象后回到consumeEvents方法继续调用InputEventReceiver的dispatchInputEvent方法 //frameworks\base\core\java\android\view\InputEventReceiver.java private void dispatchInputEvent(int seq, InputEvent event) {mSeqMap.put(event.getSequenceNumber(), seq);onInputEvent(event); }调用onInputEvent方法WindowInputEventReceiver继承InputEventReceiver调用WindowInputEventReceiver的onInputEvent方法 //frameworks\base\core\java\android\view\ViewRootImpl.java final class WindowInputEventReceiver extends InputEventReceiver {public WindowInputEventReceiver(InputChannel inputChannel, Looper looper) {super(inputChannel, looper);}Overridepublic void onInputEvent(InputEvent event) {Trace.traceBegin(Trace.TRACE_TAG_VIEW, processInputEventForCompatibility);//省略if (processedEvents ! null) {//省略} else {enqueueInputEvent(event, this, 0, true);//注意第二个参数传入的是当前对象}}enqueueInputEvent //frameworks\base\core\java\android\view\ViewRootImpl.java void enqueueInputEvent(InputEvent event,InputEventReceiver receiver, int flags, boolean processImmediately) {QueuedInputEvent q obtainQueuedInputEvent(event, receiver, flags);//省略if (processImmediately) {//processImmediately传进来的是truedoProcessInputEvents();} else {scheduleProcessInputEvents();}}doProcessInputEvents //frameworks\base\core\java\android\view\ViewRootImpl.java void doProcessInputEvents() {// Deliver all pending input events in the queue.while (mPendingInputEventHead ! null) {//省略deliverInputEvent(q);}//省略}deliverInputEvent //frameworks\base\core\java\android\view\ViewRootImpl.java private void deliverInputEvent(QueuedInputEvent q) {//省略try {//省略InputStage stage;if (q.shouldSendToSynthesizer()) {stage mSyntheticInputStage;} else {stage q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;//1}//省略if (stage ! null) {handleWindowFocusChanged();stage.deliver(q);//2} else {finishInputEvent(q);}} finally {Trace.traceEnd(Trace.TRACE_TAG_VIEW);}}注释1处设置InputStage对于触摸事件默认是忽略输入法的所以stage 为mFirstPostImeInputStage 对象。注释2处 调用mFirstPostImeInputStage 的deliver方法。 系统中有多个InputStage组成的一个链表在setView方法中设置的 //frameworks\base\core\java\android\view\ViewRootImpl.java // Set up the input pipeline. CharSequence counterSuffix attrs.getTitle(); mSyntheticInputStage new SyntheticInputStage(); InputStage viewPostImeStage new ViewPostImeInputStage(mSyntheticInputStage); InputStage nativePostImeStage new NativePostImeInputStage(viewPostImeStage,aq:native-post-ime: counterSuffix); InputStage earlyPostImeStage new EarlyPostImeInputStage(nativePostImeStage); InputStage imeStage new ImeInputStage(earlyPostImeStage,aq:ime: counterSuffix); InputStage viewPreImeStage new ViewPreImeInputStage(imeStage); InputStage nativePreImeStage new NativePreImeInputStage(viewPreImeStage,aq:native-pre-ime: counterSuffix);deliver方法的原理就是输入事件会经过这些InputStage依次处理调用onProcess方法如果事件已经被上一个消费处理了后面的stage就不会处理了。触摸事件会传递到ViewPostImeInputStage中处理 //frameworks\base\core\java\android\view\ViewRootImpl.java final class ViewPostImeInputStage extends InputStage {public ViewPostImeInputStage(InputStage next) {super(next);}Overrideprotected int onProcess(QueuedInputEvent q) {if (q.mEvent instanceof KeyEvent) {return processKeyEvent(q);} else {final int source q.mEvent.getSource();if ((source InputDevice.SOURCE_CLASS_POINTER) ! 0) {return processPointerEvent(q);} else if ((source InputDevice.SOURCE_CLASS_TRACKBALL) ! 0) {return processTrackballEvent(q);} else {return processGenericMotionEvent(q);}}}对于触摸事件调用processPointerEvent继续处理 //frameworks\base\core\java\android\view\ViewRootImpl.java private int processPointerEvent(QueuedInputEvent q) {final MotionEvent event (MotionEvent)q.mEvent;mAttachInfo.mUnbufferedDispatchRequested false;mAttachInfo.mHandlingPointerEvent true;boolean handled mView.dispatchPointerEvent(event);//1//省略return handled ? FINISH_HANDLED : FORWARD; }主要是调用mView的dispatchPointerEvent方法这里的mView是DecorView,DecorView中没有实现该方法在其父类View中实现 //frameworks\base\core\java\android\view\View.java UnsupportedAppUsagepublic final boolean dispatchPointerEvent(MotionEvent event) {if (event.isTouchEvent()) {return dispatchTouchEvent(event);} else {return dispatchGenericMotionEvent(event);}}又回到DecorView的dispatchTouchEvent方法 //frameworks\base\core\java\com\android\internal\policy\DecorView.javaOverridepublic boolean dispatchTouchEvent(MotionEvent ev) {final Window.Callback cb mWindow.getCallback();return cb ! null !mWindow.isDestroyed() mFeatureId 0? cb.dispatchTouchEvent(ev) : super.dispatchTouchEvent(ev);}这里的callback就是Activity对象调用Activity的dispatchTouchEvent方法。 //frameworks/base/core/java/android/app/Activity.javapublic boolean dispatchTouchEvent(MotionEvent ev) {if (ev.getAction() MotionEvent.ACTION_DOWN) {onUserInteraction();}if (getWindow().superDispatchTouchEvent(ev)) {//1return true;}return onTouchEvent(ev);//2}注释1处调用getWindow的superDispatchTouchEvent方法getWindow返回的是一个PhoneWindow对象。注意返回值如果返回ture的话表明消费事件注释2处Activity的onTouchEvent方法就不会执行。反之返回false的话使用onTouchEvent进行兜底onTouchEvent如果是返回true后面的InputStage就不会处理了返回false则表明继续交给后面的InputStage处理 //frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java Overridepublic boolean superDispatchTouchEvent(MotionEvent event) {return mDecor.superDispatchTouchEvent(event);}又继续调用到DecorView的superDispatchTouchEvent方法 //frameworks/base/core/java/com/android/internal/policy/DecorView.java public boolean superDispatchTouchEvent(MotionEvent event) {return super.dispatchTouchEvent(event);}调用其父类ViewGroup的dispatchTouchEvent方法。在分析这个方法之前先总结下事件是如何分发到ViewGroup的 事件是由DecorView分发给Activity然后分发给window最后又回到DecorView,再由DecorView分发给ViewGroup的。 ViewGroup接收到事件后接下来就是将事件分发给具体的view了 ViewGroup事件分发 //frameworks/base/core/java/android/view/ViewGroup.java Overridepublic boolean dispatchTouchEvent(MotionEvent ev) {//省略boolean handled false;//表明是否消费事件if (onFilterTouchEventForSecurity(ev)) {//是否符合安全策略final int action ev.getAction();final int actionMasked action MotionEvent.ACTION_MASK;// Check for interception.final boolean intercepted;//是否拦截事件if (actionMasked MotionEvent.ACTION_DOWN|| mFirstTouchTarget ! null) {final boolean disallowIntercept (mGroupFlags FLAG_DISALLOW_INTERCEPT) ! 0;//调用requestDisallowInterceptTouchEvent这个方法设置不允许拦截if (!disallowIntercept) {intercepted onInterceptTouchEvent(ev);//根据返回值判断是否允许拦截ev.setAction(action); // restore action in case it was changed} else {intercepted false;//默认是不拦截}} else {// There are no touch targets and this action is not an initial down// so this view group continues to intercept touches.intercepted true;//如果第一次的事件不是down的话直接拦截}//省略// Check for cancelation.final boolean canceled resetCancelNextUpFlag(this)|| actionMasked MotionEvent.ACTION_CANCEL;// Update list of touch targets for pointer down, if needed.final boolean split (mGroupFlags FLAG_SPLIT_MOTION_EVENTS) ! 0;TouchTarget newTouchTarget null;boolean alreadyDispatchedToNewTouchTarget false;//比较重要的参数if (!canceled !intercepted) {//不拦截也不是取消事件的话进入//省略if (actionMasked MotionEvent.ACTION_DOWN|| (split actionMasked MotionEvent.ACTION_POINTER_DOWN)|| actionMasked MotionEvent.ACTION_HOVER_MOVE) {//省略final int childrenCount mChildrenCount;if (newTouchTarget null childrenCount ! 0) {final float x ev.getX(actionIndex);final float y ev.getY(actionIndex);// Find a child that can receive the event.// Scan children from front to back.final ArrayListView preorderedList buildTouchDispatchChildList();final boolean customOrder preorderedList null isChildrenDrawingOrderEnabled();final View[] children mChildren;for (int i childrenCount - 1; i 0; i--) {//遍历子iewfinal int childIndex getAndVerifyPreorderedIndex(childrenCount, i, customOrder);final View child getAndVerifyPreorderedView(preorderedList, children, childIndex);//省略//如果子view不能接收事件或者触摸点不在该view上的话忽略这个viewif (!canViewReceivePointerEvents(child)|| !isTransformedTouchPointInView(x, y, child, null)) {ev.setTargetAccessibilityFocus(false);continue;}newTouchTarget getTouchTarget(child);//取出view的TouchTarget//忽略resetCancelNextUpFlag(child);if (dispatchTransformedTouchEvent(ev, false, child, idBitsToAssign)) {//开始分发并处理了//省略newTouchTarget addTouchTarget(child, idBitsToAssign);//进入这里表示子view消费了事件就会设置view的TouchTarget链表mFirstTouchTarget就不为空alreadyDispatchedToNewTouchTarget true;//设为truebreak;}}if (preorderedList ! null) preorderedList.clear();}//省略}}// Dispatch to touch targets.if (mFirstTouchTarget null) {// No touch targets so treat this as an ordinary view.handled dispatchTransformedTouchEvent(ev, canceled, null,TouchTarget.ALL_POINTER_IDS);//注意第三个参数为null} else {// Dispatch to touch targets, excluding the new touch target if we already// dispatched to it. Cancel touch targets if necessary.TouchTarget predecessor null;TouchTarget target mFirstTouchTarget;while (target ! null) {final TouchTarget next target.next;if (alreadyDispatchedToNewTouchTarget target newTouchTarget) {//表明子view消费了事件handled true;} else {final boolean cancelChild resetCancelNextUpFlag(target.child)|| intercepted;//判断是否是取消事件if (dispatchTransformedTouchEvent(ev, cancelChild,target.child, target.pointerIdBits)) {handled true;}//省略return handled;}首先就是看看是不是需要拦截事件判断是否通过requestDisallowInterceptTouchEvent这个方法设置了ViewGroup不允许拦截如果没有设置再判断onInterceptTouchEvent的返回值返回flase不表示不拦截。如果没有拦截则会遍历子view依次使用dispatchTransformedTouchEvent处理而如果拦截了话也是通过dispatchTransformedTouchEvent处理只不过传入的参数中第3个参数为null 来看一下dispatchTransformedTouchEvent这个方法 //frameworks/base/core/java/android/view/ViewGroup.javaprivate boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,View child, int desiredPointerIdBits) {final boolean handled;// Canceling motions is a special case. We dont need to perform any transformations// or filtering. The important part is the action, not the contents.final int oldAction event.getAction();if (cancel || oldAction MotionEvent.ACTION_CANCEL) {event.setAction(MotionEvent.ACTION_CANCEL);//代表取消事件的话将action设置为ACTION_CANCELif (child null) {handled super.dispatchTouchEvent(event);} else {handled child.dispatchTouchEvent(event);}event.setAction(oldAction);//又设置回来return handled;}//省略// Perform any necessary transformations and dispatch.if (child null) {handled super.dispatchTouchEvent(transformedEvent);//如果第三个参数传入的是空则调用自己父类的dispatchTouchEvent方法处理} else {final float offsetX mScrollX - child.mLeft;final float offsetY mScrollY - child.mTop;transformedEvent.offsetLocation(offsetX, offsetY);if (! child.hasIdentityMatrix()) {transformedEvent.transform(child.getInverseMatrix());}handled child.dispatchTouchEvent(transformedEvent);//继续分发给子view处理}// Done.transformedEvent.recycle();return handled;}dispatchTransformedTouchEvent的含义是如果child是ViewGroup的话就继续调用ViewGroup的dispatchTouchEvent方法继续向下分发如果child是view的话则调用view的dispatchTouchEvent来处理事件。如果ViewGroup拦截了事件或者ViewGroup的孩子没有消费事件的话也会调用View的dispatchTouchEvent来处理事件。来看一下view的dispatchTouchEvent方法 //frameworks/base/core/java/android/view/View.java public boolean dispatchTouchEvent(MotionEvent event) {//省略if (onFilterTouchEventForSecurity(event)) {if ((mViewFlags ENABLED_MASK) ENABLED handleScrollBarDragging(event)) {result true;}//noinspection SimplifiableIfStatementListenerInfo li mListenerInfo;if (li ! null li.mOnTouchListener ! null (mViewFlags ENABLED_MASK) ENABLED li.mOnTouchListener.onTouch(this, event)) {//设置过OnTouchListener优先调用result true;}if (!result onTouchEvent(event)) {//调用onTouchEvent方法result true;}}//省略return result;}对于事件的处理主要是判断view是不是设置过OnTouchListener如果设置过则调用其onTouch方法。如果OnTouch返回true的话表示事件在这里被消费后面的onTouchEvent就不会被调用。如果没有设置过OnTouchListener或者设置过但是OnTouch返回false则onTouchEvent会被调用。 上面的几个方法内容比较多理解起来也比较费劲用一张图总结下ViewGroup的事件分发流程 总结 可以通过重写ViewGroup的onInterceptTouchEvent方法来实现对事件的拦截可以通过调用requestDisallowInterceptTouchEvent来禁止ViewGroup对事件拦截这个优先级更高当事件都没有被View或者ViewGroup消费的话使用Activity的onTouchEvent进行兜底UP和MOVE 事件并不会重新寻找子view而是直接分发给接收DOWN事件的view
http://www.pierceye.com/news/410699/

相关文章:

  • 网站未备案被阻断怎么做中国大数据公司排名10强
  • 柳市网站优化茶叶怎么做网站销售
  • 燕郊网站建设公司什么叫动漫设计与制作
  • 瑞安做网站的公司专门做2次元图片的网站
  • 为什么自己做的网站老是404错误个人建设网站流程
  • 柳州网站建设找哪家好沈阳线上教学
  • 外贸网站免费建设做暖暖视频网站大全
  • 做机票在线预订网站手机版传奇发布网站
  • 网站建设 深圳 凡科站内推广
  • 南宁做网站外包公众号二次开发
  • 中国做网站最好的公司郑州网站建设目标
  • 各大网站平台发布信息企业官网模板免费源码
  • 第一次做网站怎么样下手威联通如何做网站
  • 网站有哪几种类型郑州建设信息网可以领证书吗
  • wordpress 百度网盘网站semseo先做哪个
  • 中企动力网站策划小程序开发平台软件
  • 做网站的公司创业泉州网页设计制作
  • 做网站一定要服务器吗做响应式网站
  • 做网站建设涉及哪些算法呼和浩特网站建设电话
  • 网站流量统计 设计做seo需要会网站开发吗
  • 网站前台用什么开发襄阳谷城网站建设
  • 网站icp备案号怎么查北京 网站建设 SEO
  • 西安做网站哪里好wordpress用户前端化
  • 宁波网站优化如何免费加速器
  • 一佰互联自助建站网站公司建设网站价格
  • 外贸网站模板免费下载wordpress英文显示改中文字体
  • 长春电商网站建设公司电话微博内容放到wordpress
  • 网站销售怎么样的商务网站模块设计时前台基础设施建设
  • 进空间的网站吗帝国建站教程
  • 做网站 业务流程图如何选择丹阳网站建设