Android中的责任链模式

来源:互联网 发布:淘宝买家电话 编辑:程序博客网 时间:2024/05/16 06:31

看看实际代码中的责任链模式

Android 5.1源码中的ViewRootImpl.java中就使用了责任链模式。

这是一张责任链的图(来自百度百科):


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

InputStage作为责任链模式中的抽象处理者(Handler)角色

定义出一个处理请求的接口。

如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。

这个角色通常由一个Java抽象类或者Java接口实现。

上图中Handler类的聚合关系给出了具体子类对下家的引用

它有一个后继者:private final InputStage mNext;

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

注意这是个final方法,意味着它的子类(具体处理者(ConcreteHandler)角色),必须遵守这个规则,不能复写这个方法。

如果QueuedInputEvent已经被处理过,那么就会有FLAG_FINISHED这个flag,那么就应该沿着责任链继续传递下去;如果尚未被处理,那么就调用onProcess方法去处理。

        /**         * Forwards the event to the next stage.         */        protected void forward(QueuedInputEvent q) {            onDeliverToNext(q);        }        /**         * 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);            }        }

这里会持续不断地向责任链中的下一个具体处理者继续传递,直到到达里责任链的尾端,那么就调用finishInputEvent结束这次处理请求。

而每一个具体的,都应该实现onProcess这个方法,去做自己需要做的处理。

onProcess方法可能返回三种结果:FORWARD,FINISH_HANDLED和FINISH_NOT_HANDLED

除了第一种表明你并不想处理,或是你虽然处理了,但还是希望后继者能继续处理,其它两种都表明你已经把这件事搞定了,你的后继者不应该再多管闲事啦。


下面看看client是如何使用的

在setView方法中

    InputStage mFirstInputStage;
    InputStage mFirstPostImeInputStage;

    InputStage mSyntheticInputStage;

                // 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);                mFirstInputStage = nativePreImeStage;                mFirstPostImeInputStage = earlyPostImeStage;

这里声明了三条责任链,其中一条是mFirstInputStage,还有一条短一些的是mFirstPostImeInputStage,还有一个更短的是mSyntheticInputStage

    private void deliverInputEvent(QueuedInputEvent q) {        if (mInputEventConsistencyVerifier != null) {            mInputEventConsistencyVerifier.onInputEvent(q.mEvent, 0);        }        InputStage stage;        if (q.shouldSendToSynthesizer()) {            stage = mSyntheticInputStage;        } else {            stage = q.shouldSkipIme() ? mFirstPostImeInputStage : mFirstInputStage;        }        if (stage != null) {            stage.deliver(q);        } else {            finishInputEvent(q);        }    }

这里会根据事件的不同,来选择使用三条责任链中的哪一条去处理这个事件,调用它的deliver方法开始处理。

0 0
原创粉丝点击