• 消息处理管道


    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;
            }
        ...
        }
    
  • 相关阅读:
    Codeforces Round #654 (Div. 2)A-E1
    android 学习receiver和发送广播,其中监听其他activity的启动demo;给activity加自定义权限只有指定有权限的app可以监听到
    任务栈Task的模式
    Activity生命周期学习笔记,和横竖切屏时候activity销毁时候保存数据和调用的方法
    Activity之间利用intent单个传递数据和批量传递数据
    Android学习-启动服务startActivityForResult调用activity并覆写onActivityResult()接收返回来的信息
    android学习之intent学习笔记
    android断点下载并显示进度,关于handler,和主线程不能联网采取子线程联网下载,和多线程下载学习
    Contentprovider学习笔记
    android学习之LayoutInflater的用法,在myAdapter getView()里将多个TextView组件压缩成一个View控件,并在listView里显示
  • 原文地址:https://www.cnblogs.com/everhad/p/6341642.html
Copyright © 2020-2023  润新知