现在的位置: 首页 > 综合 > 正文

Android中的状态机(续)

2013年10月10日 ⁄ 综合 ⁄ 共 11695字 ⁄ 字号 评论关闭

 

上周有点累,这次终于把未完成的代码给写完了,并调试完毕。

 

代码仍有待改进的地方:

1. 内部类的使用,提高代码的隐藏性以及类之间的密切关联程度(外围类与内部类之间的互访问)。

2. 其它的,希望大家多多提出建议。 联系 QQ 402320131

 

上次承诺要谈谈android开机建立PDP时状态机的变化:

大致是 DcInactiveState -> DcActivatingState -> DcActiveState

状态机在建立PDP的过程只是一个很小的部分,在其上层需要framework维护好下发和取消PDP的时机,在其下层需要modem提供NAS服务。所以PDP还是很复杂的,后续介绍下modem侧的数据业务,现在还在着手学习中。

 

提供代码:

package com.zte.liu.statemachine;

import com.zte.liu.messagehandler.HandlerThread;
import com.zte.liu.messagehandler.Looper;
import com.zte.liu.messagehandler.Message;

public class HierarchicalStateMachine {
 
 private HsmHandler mHandler;
 private HandlerThread mHandlerThread;
 
 private DefaultState defaultState = new DefaultState();
 private InactiveState inActiveState = new InactiveState();
 private ActivingState activingState = new ActivingState();
 private ActiveState activeState = new ActiveState();
 private HaltingState haltingState = new HaltingState();
 private QuitingState quitingState = new QuitingState();
 
 private static final boolean HANDLED = true;
 private static final boolean UNHANDLED = false;
 
 public static final int CMD_1 = 1;
 public static final int CMD_2 = 2;
 public static final int CMD_3 = 3;
 public static final int CMD_4 = 4;
 public static final int CMD_5 = 5;
 public static final int CMD_6 = 6;
 
 public HierarchicalStateMachine(){
  mHandlerThread = new HandlerThread();
  mHandlerThread.start();
  Looper looper = mHandlerThread.getLooper();
  mHandler = new HsmHandler(looper);
 }
 
 public void init(){
  addState(defaultState);
   addState(inActiveState, defaultState);
   addState(activingState, defaultState);
   addState(activeState, defaultState);
  addState(haltingState); 
  addState(quitingState);
  setInitialState(inActiveState);
 }
 
 private class DefaultState extends HierarchicalState{
  @Override
  public void enter() {
   System.out.println("defaultState.enter()");
  }

  @Override
  public void exit() {
   System.out.println("defaultState.exit()");
  }

  @Override
  public boolean processMessage(Message msg) {
   boolean retVal = UNHANDLED;
   switch(msg.what){
   
   }
   return retVal;
  }
 }
 
 private class InactiveState extends HierarchicalState{
  @Override
  public void enter() {
   System.out.println("inActiveState.enter()");
  }

  @Override
  public void exit() {
   System.out.println("inActiveState.exit()");
  }

  @Override
  public boolean processMessage(Message msg) {
   System.out.println("inActiveState.processMessage what=" + msgToStr(msg.what));
   boolean retVal = UNHANDLED;
   switch(msg.what){
   case CMD_1:
    sendMessage(obtainMessage(CMD_2, null));
    transitionTo(activingState);
    retVal = HANDLED;
    break;
   default:
    retVal = UNHANDLED;
   }
   return retVal;
  }
 }
 
 private class ActivingState extends HierarchicalState{
  @Override
  public void enter() {
   System.out.println("activingState.enter()");
  }

  @Override
  public void exit() {
   System.out.println("activingState.exit()");
  }

  @Override
  public boolean processMessage(Message msg) {
   System.out.println("activingState.processMessage what=" + msgToStr(msg.what));
   boolean retVal = UNHANDLED;
   switch(msg.what){
   case CMD_2:
    sendMessage(obtainMessage(CMD_3, null));
    deferMessage(msg);
    transitionTo(activeState);
    retVal = HANDLED;
    break;
   default:
    retVal = UNHANDLED;
   }
   return retVal;
  }
 }
 
 private class ActiveState extends HierarchicalState{
  @Override
  public void enter() {
   System.out.println("activeState.enter()");
  }

  @Override
  public void exit() {
   System.out.println("activeState.exit()");
  }

  @Override
  public boolean processMessage(Message msg) {
   System.out.println("activeState.processMessage what=" + msgToStr(msg.what));
   boolean retVal = UNHANDLED;
   switch(msg.what){
   case CMD_2:
    retVal = HANDLED;
    break;
   case CMD_3:
    sendMessage(obtainMessage(HsmHandler.HALTING_MESSAGE, null));
    transitionTo(haltingState);
    retVal = HANDLED;
    break; 
   default:
    retVal = UNHANDLED;
   }
   return retVal;
  }
 }

 private class HaltingState extends HierarchicalState{
  @Override
  public void enter() {
   System.out.println("haltingState.enter()");
   halt();
  }

  @Override
  public boolean processMessage(Message msg) {
   System.out.println("activeState.processMessage what=HALTING_MESSAGE");
   sendMessage(obtainMessage(HsmHandler.QUITING_MESSAGE, null));
   transitionTo(quitingState);
   return HANDLED;
  }
 }
 
 private class QuitingState extends HierarchicalState{
  @Override
  public void enter() {
   System.out.println("activeState.exit()");
  }

  @Override
  public void exit() {
   System.out.println("activeState.exit()");
  }

  @Override
  public boolean processMessage(Message msg) {
   return super.processMessage(msg);
  }
 }
 
 public void addState(HierarchicalState state){
  mHandler.addState(state, null);
 }
 
 public void addState(HierarchicalState state, HierarchicalState parent){
  mHandler.addState(state, parent);
 }
 
 public void setInitialState(HierarchicalState state){
  mHandler.setInitialState(state);
 }
 
 public void start(){
  mHandler.completeConstruction();
  mHandler.passState(haltingState, quitingState); //糟糕的做法
 }
 
 public Message obtainMessage(int what, Object obj){
  return mHandler.obtainMessage(what, obj);
 }
 
 public void sendMessage(Message msg){
  if(msg != null){
   msg.sendToTarget();
  }
 }
 
 public void deferMessage(Message msg){
  mHandler.deferMessage(msg);
 }
 
 public void transitionTo(HierarchicalState destState){
  mHandler.transitionTo(destState);
 }
 
 private String msgToStr(int what){
  String retVal = "";
  switch(what){
  case HsmHandler.QUITING_MESSAGE:
   retVal = "QUITING_MESSAGE";
   break;
  case HsmHandler.HALTING_MESSAGE:
   retVal = "HALTING_MESSAGE";
   break; 
  case CMD_1:
   retVal = "CMD_1";
   break;
  case CMD_2:
   retVal = "CMD_2";
   break;
  case CMD_3:
   retVal = "CMD_3";
   break;
  case CMD_4:
   retVal = "CMD_4";
   break;
  case CMD_5:
   retVal = "CMD_5";
   break;
  case CMD_6:
   retVal = "CMD_6";
   break;
  default:
   retVal = "UNKNOW MESSAGE";
   break;
  }
  return retVal;
 }
 
 private void halt(){
  synchronized(this){
   try {
    this.wait();
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }
 }
}

 

 

 

 

 

package com.zte.liu.statemachine;

import java.util.ArrayList;
import java.util.HashMap;

import com.zte.liu.messagehandler.Handler;
import com.zte.liu.messagehandler.Looper;
import com.zte.liu.messagehandler.Message;
import com.zte.liu.messagehandler.MessageQueue;

public class HsmHandler extends Handler {
 
 private HashMap<HierarchicalState, StateInfo> mStateInfo = new HashMap<HierarchicalState, StateInfo>();
 private HierarchicalState mInitialState = null;
 private HierarchicalState mDestState = null;
 private ArrayList<StateInfo> mInitialStateList = new ArrayList<StateInfo>();
 private ArrayList<Message> mDeferredMessages = new ArrayList<Message>();
 
 //一种糟糕的做法,将HierarchicalStateMaching中的两个状态机传入到这里。一种好的做法是将本类作为
 //HierarchicalStateMaching的内部类。
 private HierarchicalState haltingState = null;
 private HierarchicalState quitingState = null;
 
 public static final int QUITING_MESSAGE = 100;
 public static final int HALTING_MESSAGE = 101;
 
 public HsmHandler(Looper looper) {
  super(looper);
 }
 
 private class StateInfo{
  HierarchicalState state;
  HierarchicalState parentState;
  boolean active;
 }
 
 public void addState(HierarchicalState state, HierarchicalState parentState){//只在非多线程情况
  if(state == null){
   throw new RuntimeException("state cannot be null when adding state.");
  }
/*  if(mStateInfo.containsKey(state) && mStateInfo.get(state).parentState!=parentState){
   throw new RuntimeException("we cannot add a state with different parents.");
  }
*/
  if(mStateInfo.containsKey(state)){
   return;
  }
  StateInfo stateInfo = new StateInfo();
  stateInfo.state = state;
  stateInfo.parentState = parentState;
  stateInfo.active = false;
  mStateInfo.put(state, stateInfo);
 }
 
 public void setInitialState(HierarchicalState state){
  if(!mStateInfo.containsKey(state)){
   throw new RuntimeException("cannot set a initial state which is not contained in the build tree.");
  }
  mInitialState = state;
 }
 
 public void completeConstruction(){
  if(mInitialState == null){
   return;
  }
  StateInfo initialStateInfo = mStateInfo.get(mInitialState);
  while(initialStateInfo != null){
   mInitialStateList.add(initialStateInfo);
   if(initialStateInfo.parentState == null){
    initialStateInfo = null;
   }else{
    initialStateInfo = mStateInfo.get(initialStateInfo.parentState);
   }
  }
  
  invokeEnterMethods(null);
  
  performTransitions();
 }
 
 public void passState(HierarchicalState haltingState, HierarchicalState quitingState){
  this.haltingState = haltingState;
  this.quitingState = quitingState;
 }
 
 public void invokeEnterMethods(StateInfo commonStateInfo){
  int start = mInitialStateList.size() - 1;
  for(int i=mInitialStateList.size()-1; i>=0; i--){
   if(mInitialStateList.get(i) == commonStateInfo){
    start = i - 1;
    break;
   }
  }
  for(int i=start; i>=0; i--){
   StateInfo stateInfo = mInitialStateList.get(i);
   stateInfo.state.enter();
   stateInfo.active = true;
  }
 }
 
 public void invokeExitMethods(StateInfo commonStateInfo){
  for(int i=0; i<mInitialStateList.size(); i++){
   StateInfo stateInfo = (StateInfo)mInitialStateList.get(i);
   if(stateInfo != commonStateInfo){
    stateInfo.state.exit();
    stateInfo.active = false;
   }else{
    break;
   }
  }
 }
 
 public void performTransitions(){
  if(mDestState == null){
   return;
  }
  ArrayList<StateInfo> tempList = new ArrayList<StateInfo>();
  StateInfo commonStateInfo = getCommonStateInfo(mDestState, tempList);
  invokeExitMethods(commonStateInfo);
  refreshInitialStateList(commonStateInfo, tempList);
  invokeEnterMethods(commonStateInfo);
  moveDeferredMsgAtFrontQueue();
  mInitialState = mDestState;
  mDestState = null;
 }
 
 public void deferMessage(Message msg){
  mDeferredMessages.add(msg);
 }
 
 public void handleMessage(Message msg){//重写!!
  processMsg(msg);
  performTransitions();
 }
 
 public void transitionTo(HierarchicalState destState){
  mDestState = destState;
 }
 
 private StateInfo getCommonStateInfo(HierarchicalState destState, ArrayList<StateInfo> tempList){
  StateInfo stateInfo = mStateInfo.get(destState);
  while(stateInfo!=null && stateInfo.active==false){
   tempList.add(stateInfo);
   if(stateInfo.parentState == null){
    stateInfo = null;
   }else{
    stateInfo = mStateInfo.get(stateInfo.parentState);
   }
  }
  return stateInfo;
 }
 
 private void refreshInitialStateList(StateInfo commonStateInfo, ArrayList<StateInfo> tempList){
  
/*  典型的错误代码1!!执行mInitialStateList.remove(i)时,影响了mInitialStateList.size()的值。。
   for(int i=0; i<mInitialStateList.size(); i++){
   if(mInitialStateList.get(i) != commonStateInfo){
    mInitialStateList.remove(i);
   }else{
    break;
   }
  }
*/
/*  典型的错误代码2!!会出现数组越界。。  
  int initialStateListSize = mInitialStateList.size();
  for(int i=0; i<initialStateListSize; i++){
   if(mInitialStateList.get(i) != commonStateInfo){
    mInitialStateList.remove(i);
   }else{
    break;
   }
  }
*/  
  for(int i=0; i<mInitialStateList.size(); ){
   if(mInitialStateList.get(0) != commonStateInfo){
    mInitialStateList.remove(0);
   }else{
    break;
   }
  }
  if(commonStateInfo == null)
  for(int i=tempList.size()-1; i>=0; i--){
   mInitialStateList.add(0, tempList.get(i));
  }
 }
 
 private void moveDeferredMsgAtFrontQueue(){
  MessageQueue msgQueue = this.getLooper().getQueue();
  for(int i=mDeferredMessages.size()-1; i>=0; i--){
   msgQueue.addToFront(mDeferredMessages.remove(i));
  }
 }
 
 private void processMsg(Message msg){
  HierarchicalState currentState = mInitialState;
  while(!currentState.processMessage(msg)){
   currentState = mStateInfo.get(currentState).parentState;
   if(currentState == null){
    unhandledMessage(msg);
    if(isQuit(msg)){
     quitingState.exit();
    }
    break;
   }
  }
 }
 
 private void unhandledMessage(Message msg){
  System.out.println("the message " + msg.what + " is not handled.");
 }
 
 private boolean isQuit(Message msg){
  return msg.what == QUITING_MESSAGE;
 }

}

 

 

 

 

 

 

 

package com.zte.liu.statemachine;

public class MiddleUser {

 public static void main(String arg[]){
  HierarchicalStateMachine stateMachine = new HierarchicalStateMachine();
  stateMachine.init();
  stateMachine.start();
  stateMachine.sendMessage(stateMachine.obtainMessage(HierarchicalStateMachine.CMD_1, null));
  
  try {
   System.out.println("the main thread begin busy for 5 seconds...");
   Thread.sleep(7000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  System.out.println("5 seconds over...");
  synchronized(stateMachine){
   stateMachine.notifyAll();
  }
 }
}

抱歉!评论已关闭.