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

网站建设的流程ppth5网站建设的具体内容

网站建设的流程ppt,h5网站建设的具体内容,如何宣传推广自己品牌,wordpress最热文章在上一篇文章的最后#xff0c;我们发现InputDispatcher是调用了InputChannel-sendMessage把键值发送出去#xff0c;那么相应的#xff0c;也有接收键值的地方。接收函数是InputChannel-receiveMessage。 在InputConsumer::consume内找到了receiveMessage#xff…在上一篇文章的最后我们发现InputDispatcher是调用了InputChannel-sendMessage把键值发送出去那么相应的也有接收键值的地方。接收函数是InputChannel-receiveMessage。 在InputConsumer::consume内找到了receiveMessage从类名能看出来发送端与接收端相当于生产者与消费者的关系。 status_t InputConsumer::consume(InputEventFactoryInterface* factory,bool consumeBatches, nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent) {// Receive a fresh message.status_t result mChannel-receiveMessage(mMsg); }receiveMessage内调用的是socket的接收函数recv status_t InputChannel::receiveMessage(InputMessage* msg) {do {nRead ::recv(mFd, msg, sizeof(InputMessage), MSG_DONTWAIT);} while (nRead -1 errno EINTR); }事件接收端NativeInputEventReceiver 那么究竟是谁来消费这些事件呢我们在NativeInputEventReceiver里面找到了答案。 在NativeInputEventReceiver内有个事件处理函数handleEvent该函数是looperCallback的虚函数NativeInputEventReceiver作为looperCallback的子类自然有义务实现handleEvent这个函数。handleEvent就可以监听I/O事件。一旦有I/O事件如上述的socket send事件handleEvent就会被启动进行后续的处理。 int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {status_t status consumeEvents(env, false /*consumeBatches*/, -1, NULL); }既然有LooperCallbackNativeInputEventReceiver必然会有Looper。虽然Looper不是本篇文章的研究对象但是我们有必要理清下面的问题 究竟与NativeInputEventReceiver对应的这个Looper是什么这个Looper是怎样与LooperCallback关联起来的呢    实际上一切起始于ViewRootImpl的setView方法 public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) { ...//在这里传入了当前线程的Loopernew WindowInputEventReceiver(mInputChannel, Looper.myLooper()); ... }   InputEventReceiver作为WindowInputEventReceiver的子类会一起被创建出来。在InputEventReceiver的构造方法中会调用native方法nativeInit public InputEventReceiver(InputChannel inputChannel, Looper looper) {mInputChannel inputChannel;mMessageQueue looper.getQueue();mReceiverPtr nativeInit(new WeakReferenceInputEventReceiver(this),inputChannel, mMessageQueue); }   在NativeInputEventReceiver的nativeInit方法中创建了NativeInputEventReceiver对象并调用它的initialize方法 static jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,jobject inputChannelObj, jobject messageQueueObj) {...spNativeInputEventReceiver receiver new NativeInputEventReceiver(env,receiverWeak, inputChannel, messageQueue);status_t status receiver-initialize();... }   initialize方法只做了一件事就是把NativeInputEventReceiver与Looper关联起来 status_t NativeInputEventReceiver::initialize() {setFdEvents(ALOOPER_EVENT_INPUT);return OK; }void NativeInputEventReceiver::setFdEvents(int events) {if (mFdEvents ! events) {mFdEvents events;int fd mInputConsumer.getChannel()-getFd();if (events) {mMessageQueue-getLooper()-addFd(fd, 0, events, this, NULL);} else {mMessageQueue-getLooper()-removeFd(fd);}} } Looper的方法addFd实现了关联Looper与LooperCallbackNativeInputEventReceiver的功能我们先来分析一下传给addFd的参数 fdfd即inputChannel的socket fdLooper会侦测该fd的状态events即传入的ALOOPER_EVENT_INPUT只有fd的状态是INPUT的时候才会触发调用LooperCallback中的handleEvent方法this即NativeInputEventReceiver当fd状态为Input时NativeInputEventReceiver中的handleEvent方法会被调用     在consumeEvents内我们能看到调用了InputConsume::consume来接收InputDispatcher发送过来的事件 status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {for (;;) {status_t status mInputConsumer.consume(mInputEventFactory,consumeBatches, frameTime, seq, inputEvent);} }输入事件在consumeEvents内将会被处理完成其中包含了四个主要步骤 获取输入事件把输入事件转换成java也能处理的格式输入事件分发到相应窗口去处理处理结果反馈    1. 获取输入事件已在上面阐述过   2. 输入事件转换 以Key为例输入事件只是把事件内部的成员拆分然后通过JNI调用java的构造函数来生成相应的java event对象后面的事件处理都在java层 jobject inputEventObj;switch (inputEvent-getType()) {case AINPUT_EVENT_TYPE_KEY:inputEventObj android_view_KeyEvent_fromNative(env,static_castKeyEvent*(inputEvent));break;// ----------------------------------------------------------------------------jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) {jobject eventObj env-CallStaticObjectMethod(gKeyEventClassInfo.clazz,gKeyEventClassInfo.obtain,nanoseconds_to_milliseconds(event-getDownTime()),nanoseconds_to_milliseconds(event-getEventTime()),event-getAction(),event-getKeyCode(),event-getRepeatCount(),event-getMetaState(),event-getDeviceId(),event-getScanCode(),event-getFlags(),event-getSource(),NULL);if (env-ExceptionCheck()) {ALOGE(An exception occurred while obtaining a key event.);LOGE_EX(env);env-ExceptionClear();return NULL;}return eventObj; }public static KeyEvent obtain(long downTime, long eventTime, int action,int code, int repeat, int metaState,int deviceId, int scancode, int flags, int source, String characters) {KeyEvent ev obtain();ev.mDownTime downTime;ev.mEventTime eventTime;ev.mAction action;ev.mKeyCode code;ev.mRepeatCount repeat;ev.mMetaState metaState;ev.mDeviceId deviceId;ev.mScanCode scancode;ev.mFlags flags;ev.mSource source;ev.mCharacters characters;return ev;}       3.输入事件分发 这里是在java层的事件分发最终目的是为了调用到窗口的onTouch这类回调函数。 env-CallVoidMethod(receiverObj.get(),gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj);     还记得上面InputEventReceiver初始化时的流程吗是通过setView---new WindowInputEventReceiver---new InputEventReceiver---new NativeInputEventReceiver这样一步一步创建的。 通过上述的JNI调用会调用到WindowInputEventReceiver的dispatchInputEvent方法不过由于WindowInputEventReceiver并没有自己实现这个方法因此会调用父类InputEventReceiver::dispatchInputEvent内部会真正调用到WindowInputEventReceiver::onInputEvent public void dispatchInputEvent(InputEvent event) {onInputEvent(event);}   在onInputEvent内转到了ViewRootImpl这边进行处理 public void onInputEvent(InputEvent event) {enqueueInputEvent(event, this, 0, true); }void enqueueInputEvent(InputEvent event,InputEventReceiver receiver, int flags, boolean processImmediately) {doProcessInputEvents(); }由于事件队列内会包含多个事件因此在doProcessInputEvent时需要分别对所有的事件都进行分发 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;deliverInputEvent(q);}}   deliverInputEvent会调用到InputState的deliver方法 public final void deliver(QueuedInputEvent q) {if ((q.mFlags QueuedInputEvent.FLAG_FINISHED) ! 0) {forward(q);} else if (shouldDropInputEvent(q)) {finish(q, false);} else {apply(q, onProcess(q));}} 由于一开始我们的事件还没有完成因此不会带上FLAG_FINISHED而且我们的事件时一般事件并不会被丢弃因此会走apply分支。     首先会调用onProcess处理事件 protected int onProcess(QueuedInputEvent q) {if (q.mEvent instanceof KeyEvent) {return processKeyEvent(q);} else {// If delivering a new non-key event, make sure the window is// now allowed to start updating.handleDispatchDoneAnimating();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);}}}     以Key为例我们会调用到processKeyEvent private int processKeyEvent(QueuedInputEvent q) {// Deliver the key to the view hierarchy.if (mView.dispatchKeyEvent(event)) {return FINISH_HANDLED;}}然后调用了View类的dispatchKeyEvent方法最终会调用到onKey这个回调函数 public boolean dispatchKeyEvent(KeyEvent event) {// Give any attached key listener a first crack at the event.//noinspection SimplifiableIfStatementListenerInfo li mListenerInfo;if (li ! null li.mOnKeyListener ! null (mViewFlags ENABLED_MASK) ENABLED li.mOnKeyListener.onKey(this, event.getKeyCode(), event)) {return true;}}4. 处理结果反馈 然后还剩下apply这个方法需要分析。如果onProcess正常处理完成后会返回FINISH_HANDLED否则返回FINISHED_NOT_NHANDLED。 protected void apply(QueuedInputEvent q, int result) {if (result FORWARD) {forward(q);} else if (result FINISH_HANDLED) {finish(q, true);} else if (result FINISH_NOT_HANDLED) {finish(q, false);} else {throw new IllegalArgumentException(Invalid result: result);}}protected void finish(QueuedInputEvent q, boolean handled) {q.mFlags | QueuedInputEvent.FLAG_FINISHED;if (handled) {q.mFlags | QueuedInputEvent.FLAG_FINISHED_HANDLED;}forward(q);}protected void forward(QueuedInputEvent q) {onDeliverToNext(q);}protected void onDeliverToNext(QueuedInputEvent q) {if (mNext ! null) {mNext.deliver(q);} else {finishInputEvent(q);}}private void finishInputEvent(QueuedInputEvent q) {if (q.mReceiver ! null) {boolean handled (q.mFlags QueuedInputEvent.FLAG_FINISHED_HANDLED) ! 0;q.mReceiver.finishInputEvent(q.mEvent, handled);} else {q.mEvent.recycleIfNeededAfterDispatch();}recycleQueuedInputEvent(q);}           mReceiver.finishInputEvent就是NativeInputEvent的finishInputEvent status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) {status_t status mInputConsumer.sendFinishedSignal(seq, handled); }status_t InputConsumer::sendFinishedSignal(uint32_t seq, bool handled) {while (!status chainIndex-- 0) {status sendUnchainedFinishedSignal(chainSeqs[chainIndex], handled);} }status_t InputConsumer::sendUnchainedFinishedSignal(uint32_t seq, bool handled) {InputMessage msg;msg.header.type InputMessage::TYPE_FINISHED;msg.body.finished.seq seq;msg.body.finished.handled handled;return mChannel-sendMessage(msg); } 最后也是调用sendMessage把消息反馈给InputDispatcher。 到这里上层的处理已经完成接下来就是InputDispatcher的反馈处理。     InputDispatcher反馈处理 反馈处理在handleReceiveCallback中进行其中包含两个部分 接收反馈消息处理反馈消息int InputDispatcher::handleReceiveCallback(int fd, int events, void* data) {for (;;) {uint32_t seq;bool handled;status connection-inputPublisher.receiveFinishedSignal(seq, handled);if (status) {break;}d-finishDispatchCycleLocked(currentTime, connection, seq, handled);gotOne true;} }1. 接收反馈消息 接收反馈消息是调用的inputPublisher的receiveFinishedSignal方法内部还是调用了mChannel-receiveMessage status_t InputPublisher::receiveFinishedSignal(uint32_t* outSeq, bool* outHandled) {status_t result mChannel-receiveMessage(msg);}2. 处理反馈消息 处理反馈消息是调用了finishDispatchCycleLocked。 void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,const spConnection connection, uint32_t seq, bool handled) {// Notify other system components and prepare to start the next dispatch cycle.onDispatchCycleFinishedLocked(currentTime, connection, seq, handled); }   void InputDispatcher::onDispatchCycleFinishedLocked(nsecs_t currentTime, const spConnection connection, uint32_t seq, bool handled) {CommandEntry* commandEntry postCommandLocked( InputDispatcher::doDispatchCycleFinishedLockedInterruptible);}postCommandLocked其实也是发送消息给InputDispatcherThread那么在分发线程下一次处理消息的时候会首先处理doDispatchCycleFinishedLockedInterruptible。 doDispatchCycleFinishedLockedInterruptible是实际上反馈进行处理的地方其中包含了下面几个处理步骤 从waitQueue中取出所反馈的事件事件是否处理超时如果是则做超时处理从waitQueue中删除所反馈的事件立刻展开下一次的outboundQueue事件监听  void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* commandEntry) {// Handle post-event policy actions.DispatchEntry* dispatchEntry connection-findWaitQueueEntry(seq);if (eventDuration SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {String8 msg;msg.appendFormat(Window %s spent %0.1fms processing the last input event: ,connection-getWindowName(), eventDuration * 0.000001f);dispatchEntry-eventEntry-appendDescription(msg);ALOGI(%s, msg.string());}if (dispatchEntry connection-findWaitQueueEntry(seq)) {connection-waitQueue.dequeue(dispatchEntry);}// Start the next dispatch cycle for this connection.startDispatchCycleLocked(now(), connection);} }
http://www.sadfv.cn/news/185729/

相关文章:

  • 兼职网站编辑怎么做seo指哪些市场区域
  • 网站流程示意百度网站建设中的自由容器
  • 怎么才能建立一个网站卖东西查询网站建设
  • 公众号版影视网站开发中小企业网站建设公司首选
  • 宿迁做网站的网站qq访客获取
  • 太原市做网站好的科技公司域名注册证书
  • 家教网站模板下载四川建设厅证件查询
  • 珠海企业网站建设公司电子商务网站建设的规章制度
  • 网站logo怎么设计为中小型企业构建网站
  • 长沙网页网站制作塑胶模具东莞网站建设
  • wordpress建站是什么电商网站建设过程
  • 做网站和做商城的区别在哪里网页设计过程报告
  • 如何制作网站连接数据库如何把字体导入wordpress
  • 仿163源码交易平台宽屏整站源码 网站模板交易平台源码技术支持 东莞网站建设石材
  • 单页网站制作建站仿站wordpress 中国 论坛
  • 如何让网站关键词搜录wordpress 检索
  • 做网站的具体步骤昆明做网站要多少钱
  • 能打开网站的浏览器莱芜网站推广
  • 教你如何建立网站营销型的物流网站模板
  • dedecms的网站如何添加个引导页微信群公告如何做网站链接
  • 全国建设工程招标信息网站浦东新区手机网站设计
  • sedo这种多语言网站怎么建设小程序制作侧拉切换
  • 制作公司网站 优帮云如何建设网站并与数据库相连
  • 成都网站建设益友网络个人微信crm系统
  • 电商网站建设与维护试题宁波海曙网站开发公司电话
  • 宁夏银川做网站的公司扬州网站推广
  • 有没有好网站推荐wordpress后台怎么登入
  • 站长如何做导航网站可以免费发布招聘网站
  • 网站建设搞笑广告词手机网站报价表
  • 营销型网站开发流程包括logo设计网站排行榜