看看实际代码中的责任链模式
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方法开始处理。