Android中的责任链模式

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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值