相关概念有限状态机/finite-state machine (FSM): 具有有限状态数目的状态机,是最常用的状态机,也是一般讨论状态机时所指的对象无限状态机/Infinite State Machine:具有无限状态数目的状态机,很少用到状态/state:状态可达到的某个状态状态转换/transition:状态机的从一个状态转变为另一个状态输入/input/事件/event:可被被状态机接收并处理的事件输入,可能导致状态变动

一般状态的UML表示如下:

状态机的一般实现

一个播放器示例

public enum State { IDLE, DATA_SOURCE, PREPARING, PREPARED, STARTING, STARTED, BUFFERING, READY, SWITCHING_PROGRAM, SWITCHING_CHANNEL, SWITCHING_DEFINITION, SWITCHING_ENGINE, STOPPING, RELEASING, ERROR}

状态的顺序很重要,尽量按照stack的形式,对于特殊状态特殊处理,比如error。

public class Event { public static class SetDataSourceEvent extends LoopEvent { public Uri uri; public SetDataSourceEvent() {} public SetDataSourceEvent(Uri uri) { this.uri = uri; } } public static class PrepareEvent extends LoopEvent {} public static class StartEvent extends LoopEvent {} public static class SwitchChannelEvent extends LoopEvent { public int cateIndex; public int channelIndex; public SwitchChannelEvent() {} public SwitchChannelEvent(int cateIndex, int channelIndex) { this.cateIndex = cateIndex; this.channelIndex = channelIndex; } } public static class SwitchDefinitionEvent extends LoopEvent { public int definition; public SwitchDefinitionEvent() {} public SwitchDefinitionEvent(int definition) { this.definition = definition; } } public static class SwitchEngineEvent extends LoopEvent { public String engine; public SwitchEngineEvent() {} public SwitchEngineEvent(String engine) { this.engine = engine; } } public static class StopEvent extends LoopEvent {}}

public abstract class Action { protected abstract void doAction() throws Exception;}public class Action1 extends Action { protected void doAction() throws Exception { // xxxx // update state }}...

public abstract class LoopStateMachine { private ActionThread mActionThread = new ActionThread("LoopActionThread"); private BlockingQueue<Action> mActionQueue = new ArrayBlockingQueue<>(100); private State mState; public void sendEvent(Event event) { // 根据event创建action并塞入mActionQueue } private class ActionThread extends Thread { public ActionThread(String name) { super(name); } @Override public void run() { super.run(); while (true) { try { LoopAction action = mActionQueue.take(); action.doAction(); } catch (Exception e) { Logger.w(TAG, "$ActionThread#run(): exception", e); mState = State.ERROR; // 继续 } } } }}