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

代码仍有待改进的地方:

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

更多相关文章

  1. 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
  2. Android(安卓)上传图片到 Asp.Net 服务器的问题
  3. Android性能优化---布局优化
  4. Android流媒体开发之路二:NDK C++开发Android端RTMP直播推流程序
  5. qt for android中文字体显示异常解决方案
  6. Android之工程目录介绍
  7. Android(安卓)Proguard介绍
  8. android(基于监听)的事件处理
  9. Android(安卓)HAL实例学习-Jollen的mokoid工程编译篇

随机推荐

  1. 在android的eclipse开发环境中配置git环
  2. [置顶] Mc小冰总结的Android开发工程师面
  3. Android 基础——第一行代码读书笔记(1)
  4. Ubuntu Android开发环境配置
  5. android开发工具合集(Zipalign)
  6. Android Sqlite 数据库—基础篇
  7. android平台的三个编译命令----make,mm,m
  8. Android微件(续)
  9. Android"重力加速度传感器"从驱动到应用
  10. 《Android构建MVVM》系列(一) 之 MVVM架