zoukankan      html  css  js  c++  java
  • 消息处理管道

    TODO: 待写

    # 消息处理管道 一个App看作是系统,外部输入消息需要经过一系列处理,涉及不同接收者。消息处理的跟踪(Trace)和结果的保存。 比如设计一个用来接收服务器推送消息的处理框架?

    以Android中处理InputEvent的设计作为借鉴。

    案例

    android.view.ViewRootImpl.deliverInputEvent()分发消息
    InputStage处理阶段

    使用了什么模式?
    解决了哪些问题?
    什么时候使用?

    处理的阶段:InputStage

    InputStage mFirstInputStage;
    
    private void deliverInputEvent(QueuedInputEvent q) {        
            try {            
    
                InputStage stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;
                if (stage != null) {
                    stage.deliver(q);
                } else {
                    finishInputEvent(q);
                }
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }
    }
    
    /**
         * Base class for implementing a stage in the chain of responsibility
         * for processing input events.
         * <p>
         * Events are delivered to the stage by the {@link #deliver} method.  The stage
         * then has the choice of finishing the event or forwarding it to the next stage.
         * </p>
         */
        abstract class InputStage {
            private final InputStage mNext;
    
            protected static final int FORWARD = 0;
            protected static final int FINISH_HANDLED = 1;
            protected static final int FINISH_NOT_HANDLED = 2;
    
            /**
             * Creates an input stage.
             * @param next The next stage to which events should be forwarded.
             */
            public InputStage(InputStage next) {
                mNext = next;
            }
    
            /**
             * Delivers an event to be processed.
             */
            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));
                }
            }
    
            /**
             * Marks the the input event as finished then forwards it to the next stage.
             */
            protected void finish(QueuedInputEvent q, boolean handled) {
                q.mFlags |= QueuedInputEvent.FLAG_FINISHED;
                if (handled) {
                    q.mFlags |= QueuedInputEvent.FLAG_FINISHED_HANDLED;
                }
                forward(q);
            }
    
            /**
             * Forwards the event to the next stage.
             */
            protected void forward(QueuedInputEvent q) {
                onDeliverToNext(q);
            }
    
            /**
             * Applies a result code from {@link #onProcess} to the specified event.
             */
            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);
                }
            }
    
            /**
             * Called when an event is ready to be processed.
             * @return A result code indicating how the event was handled.
             */
            protected int onProcess(QueuedInputEvent q) {
                return FORWARD;
            }
    
            /**
             * Called when an event is being delivered to the next stage.
             */
            protected void onDeliverToNext(QueuedInputEvent q) {
                if (mNext != null) {
                    mNext.deliver(q);
                } else {
                    finishInputEvent(q);
                }
            }
    
            protected boolean shouldDropInputEvent(QueuedInputEvent q) {
                if (mView == null || !mAdded) {
                    Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent);
                    return true;
                } else if (!mAttachInfo.mHasWindowFocus &&
                      !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) &&
                      !isTerminalInputEvent(q.mEvent)) {
                    // If this is a focused event and the window doesn't currently have input focus,
                    // then drop this event.  This could be an event that came back from the previous
                    // stage but the window has lost focus in the meantime.
                    Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent);
                    return true;
                }
                return false;
            }
        ...
        }
    
  • 相关阅读:
    关于RecyclerView你知道的不知道的都在这了(下)
    关于RecyclerView你知道的不知道的都在这了(上)
    读书笔记--Android Gradle权威指南(下)
    读书笔记--Android Gradle权威指南(上)
    写完批处理脚本,再写个Gradle脚本,解放双手
    写个批处理脚本来帮忙干活--遍历文件夹&字符串处理
    发布开源库到JCenter所遇到的一些问题记录
    swift GCD使用指南
    挣值管理(PV、EV、AC、SV、CV、SPI、CPI)记忆之我见
    一、通过企业账号申请证书
  • 原文地址:https://www.cnblogs.com/everhad/p/6341642.html
Copyright © 2011-2022 走看看