消息处理管道

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.
     * 

* 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. *

*/ 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; } ... }

你可能感兴趣的:(消息处理管道)