读书人

Android学习 StateMachine与State方式

发布时间: 2012-07-01 13:15:00 作者: rapoo

Android学习 StateMachine与State模式

一 State模式

意图:

  允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。(Objects for States)

  对象内部状态决定行为方式,对象状态改变行为方式改变;但这里为何要强调内部状态,

外部状态改变也同样会影响行为方式的改变,通常外部状态的改变都会反映到内部状态上来。

  Command模式是将命令请求封装成一个为对象,将不同的请求对象参数化以达到同样的调用执行不同的命令;

同样State模式是将对象的状态封装成一个对象,是在不同的状态下同样的调用执行不同的操作。

?

适用性:

  l? 一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态来改变行为;

  l? 一个操作中含有庞大的多分支条件语句,且这些分支依赖于该对象的状态;

    根据对象的状态改变行为采用了分支语句的实现方式,解决如此多的分支语句,

    将分支语句放入一个类中进行处理,即将对象的状态封装成为一个独立对象;

结构:

??????

    Android学习 StateMachine与State方式

  Context:维护一个State的子类实例,这个实例定义当前的状态;

  State:定义一个接口以封装与Context的一个特定状态相关的行为;

?

Context与State交互:

  l? Context将与状态相关的请求委托给当前的ConcreteState处理;

  l? Context可将自身作为一个参数传递给处理该请求的状态,使得状态对象在必要的时访问Context;

  l? Context是客户使用的主要接口,客户可用对象来配置一个Context,一旦一个Context配置完毕,

    它的客户不再需要直接与状态对象打交道;

  l? Context或ConcreteState子类都可以决定哪个状态是另外哪一个的后继者,以及是在何种条件下进行转换;

?

理解:

  将对象的状态封装成一个对象,特定的状态下具体的操作行为不同,所以将对象的状态封装成一个对象目地,

是为了得到不同的行为方式;封装对象的状态是将对象的状态与行为封装在一起;可以解决庞大的分支语句带来

程序阅读性差和不便于进行扩展问题,使整个结构变得更加清晰明了,降低程序管理的复杂性提高灵活度。

  解决不断根据内部变量属性改变来决定状态,这样对于复杂多状态的维护变得相对麻烦;而要保持对象的状态一致性,

使状态是作为一个对象进行改变,从Context角度来理解,状态的改变就是原子性——设置一个新的状态State对象即可,

是特定状态内部变量属性更改达到一致性。

  谁定义状态转换呢?  一是由Context对象来改变,容易控制对象的状态,保持对象之间完全独立;

二是由State对象来改变设定其下一个状态,很容易控制状态改变,保证状态的连续性;由Context来改变

状态不知道何时该去改变状态比较合适,不知道当前状态处于什么情况,就需要等待当前状态执行结果然后决定;

由State对象本身来改变,则需要Context提供相应的接口来设定当前的状态,并且需要知道下一个状态对象是谁,

至少是一个状态需要被了解,造成各状态对象之间产生了很强的的依赖性,并且在下一个状态不确定的情况下,

在某种情况下才被触发,State对象本身很难去决定下一个对象是谁,你想用State来监听者些情况的触发吗?

NO不可能的;所以需要在具体问题中去权衡选择。

  State对象的创建与销毁,一是当需要State对象创建它切换后销毁它;二是提前创建状态切换不销毁。

对于不同的语言和使用环境,采取的策略会不同。

?????? 下面来看一下Android平台中对于State模式的应用。

?

二 Android中StateMachine机制

  对与State改变切换这种常见常用的处理,只是各个平台框架中处理的方法不同,

这种在处理多状态较为复杂的大部分场景都能见到的策略——状态机(StateMachine)。

在Android中使用的了StateMachine机制就是一个State模式的应用, StateMachine是非常的强大和精妙。

  下面先简单看一下这个StateMachine。

?

StateMachine类作用:

  The state machine defined here is a hierarchical state machine which processes

messages and can have states arranged hierarchically.

  这里的状态机是一个分层处理消息的状态机,并且是能够有分层排列状态。

下面通过这个类层次的结构来:

?

    Android学习 StateMachine与State方式

这样就构成了State模式:

?????? Context——StateMachine

?????? State ? ——State

?

  StateMachine的构造函数都是protected类型,不能实例化;都是由其子类进行初始化操作;

protected StateMachine(String name) 
{  mSmThread = new HandlerThread(name);  mSmThread.start();  Looper looper = mSmThread.getLooper();  initStateMachine(name, looper);}

?

  但是这个类具体是怎么构成上述的层次结构状态和层次消息处理仍然不明确。

  下面继续看一下这个类各个模块的作用。

?

三 Android 中StateMachine模块分析

?

1 State Machine各个模块作用

?

State

public class State implements IState
{  protected State() {}  public void enter() {}  public void exit() {}  public boolean processMessage(Message msg) {}  public String getName() {}}

  状态的基类,stateMachine中的状态都是由State派生而来,构造函数protected,不能实例化;

?

StateMachine三个内部类:

ProcessedMessageInfo:  保存已处理消息的信息

public static class ProcessedMessageInfo 
{  private int what; //用户定义消息标识  private State state; //处理当前消息的状态  private State orgState; //消息未被处理前当前的状态}

?

ProcessedMessages

  存储StateMachine最近处理的一些消息,需要保存最近处理的消息条数默认20,可以用户自己设定最大数目。

private static class ProcessedMessages {  private static final int DEFAULT_SIZE = 20;  private Vector<ProcessedMessageInfo> mMessages = 
    new Vector<ProcessedMessageInfo>();  private int mMaxSize = DEFAULT_SIZE;  private int mOldestIndex = 0;  private int mCount = 0;}

?

SmHandler三个内部类:

StateInfo:存储当前State,和其parentState,以及是否激活状态;用来构建树形层次结构模型

private class StateInfo 
{  /** the state */  State state;  /** The parent of this state, null if there is no parent */  StateInfo parentStateInfo;  /** True when the state has been entered and on the stack */  boolean active;}

?

HaltingStateQuittingState

?????? 都是State的 派生类,用于在状态停止和放弃之后处理的一些事情;都重写了ProcessMessage方法,

在StateMachine没有实际行动仅仅保留用于扩展。

???????整个SmHandle是消息处理派发和状态控制切换的核心,运行在单独的线程上。

SmHandle

  数据成员不少,列出其中关键的一些;

private static class SmHandler extends Handler 
{  /** The current message */  private Message mMsg;  /** A list of messages that this state machine has processed */  private ProcessedMessages mProcessedMessages =    new ProcessedMessages();  /** Stack used to manage the current hierarchy of states */  private StateInfo mStateStack[];  /** The map of all of the states in the state machine */  private HashMap<State, StateInfo> mStateInfo =    new HashMap<State, StateInfo>();  /** The initial state that will process the first message */  private State mInitialState;
  /** The destination state when transitionTo has been invoked */  private State mDestState;}

?

SmHandle是构建StateMachine的核心,运行在独立的线程上,有三个功能:

读书人网 >Android

热点推荐