Android中的状态机 机制

来源:互联网 发布:下载 windows 10 编辑:程序博客网 时间:2024/06/06 11:43

 

 前面说过消息注册机制是MessageHandler的一个应用,它的好处就是能在程序中自如地控制消息注册和消息发送两个步骤。

 

但是很多情况下,问题的解决是在很多个环节完成的,每个环节理解成特定的状态,在每个状态下都会有新消息的发送或者新状态的切换。那么设计就需要考虑如何将Message的处理操作放到指定的状态机中,这是程序设计的关键。

 

总体思想:

(1)先初始化状态机,设置初始状态。

(2)内存中加载handler对象,要知道所有Message的处理都的经过它,所以在复写handleMessage的时候需要将当前Message分发到当前最新状态。

 

下面是模拟程序,刚写的,没调试,而且不全面,只写了骨架,但更直观便于阅读。明天调试看看,得出完整版本的,最好结合PDP建立过程讲解PDP建立的状态机过程。

这里列举3个类:

package com.zte.liu.statemachine;

public class HierarchicalState {
 
 public void enter(){
  
 }
 public void exit(){
  
 }
 public void processMessage(){
  
 }

}

 

 

 

 

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();
 
 public HierarchicalStateMachine(){
  mHandlerThread = new HandlerThread();
  mHandlerThread.start();
  Looper looper = mHandlerThread.getLooper();
  mHandler = new HsmHandler(looper);
 }
 
 private class DefaultState extends HierarchicalState{
  
 }
 
 private class InactiveState extends HierarchicalState{
  
 }
 
 private class ActivingState extends HierarchicalState{
  
 }
 
 private class ActiveState extends HierarchicalState{
  
 } 

 private class HaltingState extends HierarchicalState{
  
 }
 
 private class QuitingState extends HierarchicalState{
  
 }
 
 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();
 }
 
 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);
 }
}

 

 

 

 

 

 

 

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>();
 
 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 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()-1; 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();
 }
 
 public void deferMessage(Message msg){
  mDeferredMessages.add(msg);
 }
 
 public void handleMessage(Message msg){//重写!!
  ///////////////////////////////////////
  
  //////////////////////////////////////
 }
 
 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){
  for(int i=0; i<mInitialStateList.size()-1; i++){
   if(mInitialStateList.get(i) != commonStateInfo){
    mInitialStateList.remove(i);
   }
  }
  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.get(i));
  }
 }

}


 

原创粉丝点击