StateMachine使用及源码解读(2)

使用

实现自己的状态只需要继承State类,实现processMessage方法即可

public class State implements IState {

protected State() {
}

@Override
public void enter() {
}

@Override
public void exit() {
}

@Override
public boolean processMessage(Message msg) {
return false;
}

@Override
public String getName() {
String name = getClass().getName();
int lastDollar = name.lastIndexOf(‘$’);
return name.substring(lastDollar + 1);
}
}

创建自己的MyStateMachine类,继承自StateMachine。初始化自定义状态,将状态add进去,调用setInitialState和start即可。

public class MyStateMachine extends StateMachine{
private BaseState mBaseState = new BaseState();
private AState mAState = new AState();
private BState mBState = new BState();
private CState mCState = new CState();

public NewStateMachine(String name) {
super(name);
addState(mAState, mBaseState);
addState(mBState, mAState);
addState(mCState, mBaseState);
setInitialState(mBaseState);
start();
}
}

源码解读

StateMachine构造方法

// 重写SmHandler的handleMessage方法
private SmHandler mSmHandler;
// 内部其实是一个HandlerThread
private HandlerThread mSmThread;

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

private void initStateMachine(String name, Looper looper) {
mName = name;
mSmHandler = new SmHandler(looper, this);
}

SmHandler

private static class SmHandler extends Handler{
// 管理当前活跃的状态栈
private StateInfo mStateStack[];
// Halting状态
private HaltingState mHaltingState = new HaltingState();
// Quiting状态
private QuittingState mQuittingState = new QuittingState();

// map,存储State和StateInfo的对应表
private HashMap<State, StateInfo> mStateInfo = new HashMap<State, StateInfo>();
// 初始状态
private State mInitialState;
// 目标状态
private State mDestState;

private SmHandler(Looper looper, StateMachine sm) {
super(looper);
mSm = sm;
// 默认将HaltingState和QuittingState加入状态机
addState(mHaltingState, null);
addState(mQuittingState, null);
}
}

QuittingState

/**

  • State entered when a valid quit message is handled.
    */
    private class QuittingState extends State {
    @Override
    public boolean processMessage(Message msg) {
    // 所有消息都不作处理
    return NOT_HANDLED;
    }
    }

HaltingState

/**

  • State entered when transitionToHaltingState is called.
    */
    private class HaltingState extends State {
    @Override
    public boolean processMessage(Message msg) {
    // 和quitting的不同在于,可以处理消息,所有的消息都调用haltedProcessMessage
    mSm.haltedProcessMessage(msg);
    return true;
    }
    }

StateMachine#start

public void start() {
// mSmHandler有可能为空,如果调用了quit,会被置空。如果调用了quit,statemachine的很多资源会被释放,调用start无法再次开启
if (mSmHandler == null) return;
// 初始化一些参数
mSmHandler.completeConstruction();
}

private final void completeConstruction() {
// 获取整个状态表的深度
int maxDepth = 0;
for (StateInfo si : mStateInfo.values()) {
int depth = 0;
for (StateInfo i = si; i != null; depth++) {
i = i.parentStateInfo;
}
if (maxDepth < depth) {
maxDepth = depth;
}
}
// 根据深度来初始化StateStack和TempStateStack
mStateStack = new StateInfo[maxDepth];
mTempStateStack = new StateInfo[maxDepth];
setupInitialStateStack();
// 发送SM_INIT_CMD message,异步调用enter方法
sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));
}

SmHandler#setupInitialStateStack

// 收到SM_INIT_CMD消息后,转移到初始状态
private final void setupInitialStateStack() {
StateInfo curStateInfo = mStateInfo.get(mInitialState);
// 将初始状态及其所有父状态加入tempStack
for (mTempStateStackCount = 0; curStateInfo != null; mTempStateStackCount++) {
mTempStateStack[mTempStateStackCount] = curStateInfo;
curStateInfo = curStateInfo.parentStateInfo;
}
// 清空StateStack
mStateStackTopIndex = -1;
// 将tempStateStack移动到StateStack
moveTempStateStackToStateStack();
}

SmHandler#addState

private final StateInfo addState(State state, State parent) {
StateInfo parentStateInfo = null;
if (parent != null) {
parentStateInfo = mStateInfo.get(parent);
if (parentStateInfo == null) {
// 如果parent未添加,手动添加
parentStateInfo = addState(parent, null);
}
}
StateInfo stateInfo = mStateInfo.get(state);
if (stateInfo == null) {
// 创建StateInfo,添加到map中
stateInfo = new StateInfo();
mStateInfo.put(state, stateInfo);
}
// 重复指定不一样的parent,抛异常
if ((stateInfo.parentStateInfo != null) &&
(stateInfo.parentStateInfo != parentStateInfo)) {
throw new RuntimeException(“state already added”);
}
// stateInfo保存了当前状态、父状态、是否active
stateInfo.state = state;
stateInfo.parentStateInfo = parentStateInfo;
// 调用enter后,active为true,exit后,active为false
stateInfo.active = false;
return stateInfo;
}

SmHandler#handleMessage

@Override
public final void handleMessage(Message msg) {
mMsg = msg;
if (mIsConstructionCompleted) {
// 已经初始化完之后的常规路径
processMsg(msg);
} else if (!mIsConstructionCompleted &&
(mMsg.what == SM_INIT_CMD) && (mMsg.obj == mSmHandlerObj)) {
// 未初始化完的路径,调用enter
mIsConstructionCompleted = true;
invokeEnterMethods(0);
} else {
throw new RuntimeException("StateMachine.handleMessage: " +
"The start method not called, received msg: " + msg);
}
// 执行transitions
performTransitions();
}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门**

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值