Android中的设计模式(2)

如上所示,当设定mS1为初始状态时,会依次调用mP1 mS1的enter函数来初始化环境。如下代码所展示的,mStateStack是状态从父到子的一个StateInfo数组。StateInfo是和一个State绑定的。包含了当前状态,父状态,当前是否激活。

private final void invokeEnterMethods(int stateStackEnteringIndex) { for (int i = stateStackEnteringIndex; i <= mStateStackTopIndex; i++) { if (mDbg) Log.d(TAG, "invokeEnterMethods: " + mStateStack[i].state.getName()); mStateStack[i].state.enter(); mStateStack[i].active = true; } }

可以看看这个数组的初始化过程:
1,首先依次把当前状态及循环追溯父类的状态保存在mTempStateStack临时的栈中。

private final void setupInitialStateStack() { if (mDbg) { Log.d(TAG, "setupInitialStateStack: E mInitialState=" + mInitialState.getName()); } StateInfo curStateInfo = mStateInfo.get(mInitialState); for (mTempStateStackCount = 0; curStateInfo != null; mTempStateStackCount++) { mTempStateStack[mTempStateStackCount] = curStateInfo; curStateInfo = curStateInfo.parentStateInfo; } // Empty the StateStack mStateStackTopIndex = -1; moveTempStateStackToStateStack(); }

2,然后把临时的栈倒序,并保存在mStateStack中,这时mStateStack从0开始就是最顶端的父类,然后依次保存子类。

private final int moveTempStateStackToStateStack() { int startingIndex = mStateStackTopIndex + 1; int i = mTempStateStackCount - 1; int j = startingIndex; while (i >= 0) { if (mDbg) Log.d(TAG, "moveTempStackToStateStack: i=" + i + ",j=" + j); mStateStack[j] = mTempStateStack[i]; j += 1; i -= 1; } mStateStackTopIndex = j - 1; if (mDbg) { Log.d(TAG, "moveTempStackToStateStack: X mStateStackTop=" + mStateStackTopIndex + ",startingIndex=" + startingIndex + ",Top=" + mStateStack[mStateStackTopIndex].state.getName()); } return startingIndex; } 状态机运行

状态机启动之后,通过调用状态机的StateMachine.obtainMessage()函数来获取消息,通过StateMachine.sendMessage()函数来发送消息,状态机接收到这个消息后,就会调用当前状态的processMessage()函数来根据当前状态中定义好的方式,进行状态的切换。

public final void handleMessage(Message msg) { if (mDbg) Log.d(TAG, "handleMessage: E msg.what=" + msg.what); /** Save the current message */ mMsg = msg; if (mIsConstructionCompleted) { /** Normal path */ processMsg(msg); ......
private final void processMsg(Message msg) { StateInfo curStateInfo = mStateStack[mStateStackTopIndex]; if (mDbg) { Log.d(TAG, "processMsg: " + curStateInfo.state.getName()); } if (isQuit(msg)) { transitionTo(mQuittingState); } else { while (!curStateInfo.state.processMessage(msg)) { //调用当前状态的processMessage()函数 curStateInfo = curStateInfo.parentStateInfo;//如果当前状态没有处理,则将父状态设为当前状态,继续父状态的ProcessMessage函数处理 if (curStateInfo == null) {//如果不再有父状态了,则作为未处理的信息打印Log mSm.unhandledMessage(msg); break; } if (mDbg) { Log.d(TAG, "processMsg: " + curStateInfo.state.getName()); } }

状态机中的状态,可能会有父状态,如果当前状态的processMessage函数返回false 或者 NOT_HANDLED,就会向上调用父状态的processMessage函数进行处理,如果最顶端的父状态也没处理,那就交给unhandledMessage函数做最后的处理(一般是丢掉,当然可以自己定义最后的处理函数)。随后

当所有的处理结束后,状态机可以调用transitionToHaltingState进入HaltingState(StateMachine内部预设的状态)。并调用到自定义StateMachine的onHalting()函数,进入HaltingState状态后,所有随后发来的消息,都会导致HaltingState的haltedProcessMessage的调用(同样需要继承实现自定义处理)。

如果想要停止状态机,可以调用quit或者abort方法,从而进入QuittingState,并在下一次处理时,退出HandlerThread线程,清理内部各个对象。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/21cf657be5adb10b5c3e5a3111333ab9.html