Android中的状态机(续)

简介:
 

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

 

代码仍有待改进的地方:

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();
  }
 }
}

相关文章
|
存储 Java API
一文详解 Android状态机StateMachine 使用方式及实现原理
`StateMachine`不是`Android SDK`中的相关API,是存在于`frameworks`层源码中的一个Java类。通过这篇文章探究一下其使用方式以及实现原理。
1081 0
一文详解 Android状态机StateMachine 使用方式及实现原理
|
Android开发 开发者
【Android 高性能音频】AAudio 状态机 ( 创建 | 打开 Open | 开始 Started | 暂停 Paused | 刷写 Flushed | 停止 Stopped | 关闭 )
【Android 高性能音频】AAudio 状态机 ( 创建 | 打开 Open | 开始 Started | 暂停 Paused | 刷写 Flushed | 停止 Stopped | 关闭 )
421 0
|
19天前
|
XML 存储 Java
探索安卓开发之旅:从基础到进阶
【9月更文挑战第37天】安卓开发,一个充满无限可能的领域。它不仅关乎技术的深度与广度,更关乎开发者的成长与突破。本文将带你走进安卓开发的世界,从基础知识的学习到进阶技巧的掌握,一起感受编程的魅力与乐趣。
|
13天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
13天前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
51 1
|
16天前
|
Android开发
Android开发表情emoji功能开发
本文介绍了一种在Android应用中实现emoji表情功能的方法,通过将图片与表情字符对应,实现在`TextView`中的正常显示。示例代码展示了如何使用自定义适配器加载emoji表情,并在编辑框中输入或删除表情。项目包含完整的源码结构,可作为开发参考。视频演示和源码详情见文章内链接。
41 4
Android开发表情emoji功能开发
|
14天前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
42 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
12天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件基础与进阶
【10月更文挑战第5天】在Android应用开发中,自定义控件是提升用户体验和界面个性化的重要手段。本文将通过浅显易懂的语言和实例,引导你了解自定义控件的基本概念、创建流程以及高级应用技巧,帮助你在开发过程中更好地掌握自定义控件的使用和优化。
25 10