android 4.0.4: /frameworks/base/core/java/com/android/internal/util/StateMachine.java
StateMachine状态机中,会创建HandlerThread线程,和依附该线程的Handler;消息处理都是在HandlerThread中执行
framework层的好几个状态机,都是在StateMachine基础上实现的,比如:WifiStateMachine、DhcpStateMachine、WifiWatchdogStateMachine。。。
http://androidxref.com/4.0.4/xref/frameworks/base/core/java/com/android/internal/util/StateMachine.java
SmHandler:
/**
* Handle messages sent to the state machine by calling
* the current state's processMessage. It also handles
* the enter/exit calls and placing any deferred messages
* back onto the queue when transitioning to a new state.
*/
@Override
public final void handleMessage(Message msg) {
if (mDbg) Log.d(TAG, "handleMessage: E msg.what=" + msg.what);
/** Save the current message */
mMsg = msg;
/**
* Check that construction was completed
*/
if (!mIsConstructionCompleted) {
Log.e(TAG, "The start method not called, ignore msg: " + msg);// 在状态机没有启动之前,收到msg,只是打印error日志
return;
}
/**
* Process the message abiding by the hierarchical semantics
* and perform any requested transitions.
*/
processMsg(msg);
performTransitions();
if (mDbg) Log.d(TAG, "handleMessage: X");
}
/**
* Complete the construction of the state machine.
*/
private final void completeConstruction() {
if (mDbg) Log.d(TAG, "completeConstruction: E");
/**
* Determine the maximum depth of the state hierarchy
* so we can allocate the state stacks.
*/
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;
}
}
if (mDbg) Log.d(TAG, "completeConstruction: maxDepth=" + maxDepth);
mStateStack = new StateInfo[maxDepth];
mTempStateStack = new StateInfo[maxDepth];
setupInitialStateStack();
/**
* Construction is complete call all enter methods
* starting at the first entry.
*/
mIsConstructionCompleted = true;
mMsg = obtainMessage(SM_INIT_CMD);
invokeEnterMethods(0);// 初始状态的enter方法,在调用线程中执行;即如果在UI线程中,调用状态机的start()方法,则初始状态的enter方法,在UI线程中执行,如果enter方法中有耗时的操作,肯定会占用UI线程的资源
/**
* Perform any transitions requested by the enter methods
*/
performTransitions();// 如果初始状态的enter方法中,有跳转,即调用了transitionTo方法,则初始状态的exit方法、新状态的enter方法,也都会在调用线程中执行,依次类推,也会进一步占用调用线程的资源
if (mDbg) Log.d(TAG, "completeConstruction: X");
}
StateMachine:
/**
* Start the state machine.
*/
public void start() {
// mSmHandler can be null if the state machine has quit.
if (mSmHandler == null) return;
/** Send the complete construction message */
mSmHandler.completeConstruction();
}
///
android 4.1.1: /frameworks/base/core/java/com/android/internal/util/StateMachine.java
http://androidxref.com/4.1.1/xref/frameworks/base/core/java/com/android/internal/util/StateMachine.java
SmHandler:
/**
* Handle messages sent to the state machine by calling
* the current state's processMessage. It also handles
* the enter/exit calls and placing any deferred messages
* back onto the queue when transitioning to a new state.
*/
@Override
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);
} else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD) && (mMsg.obj == mSmHandlerObj)) {
/** Initial one time path. */
mIsConstructionCompleted = true;// 调用start方法,走该分支一次;后面处理消息,都走前面的分支processMsg;(在HandlerThread线程中执行)
invokeEnterMethods(0);
} else {
throw new RuntimeException("StateMachine.handleMessage: " + "The start method not called, received msg: " + msg);// 这里也是修改点,状态机没有启动之前,即没有调用start()方法之前,在4.0.4上,是打印error日志;在4.1.1上,则是
}
performTransitions();
if (mDbg) Log.d(TAG, "handleMessage: X");
}
/**
* Complete the construction of the state machine.
*/
private final void completeConstruction() {
if (mDbg) Log.d(TAG, "completeConstruction: E");
/**
* Determine the maximum depth of the state hierarchy
* so we can allocate the state stacks.
*/
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;
}
}
if (mDbg) Log.d(TAG, "completeConstruction: maxDepth=" + maxDepth);
mStateStack = new StateInfo[maxDepth];
mTempStateStack = new StateInfo[maxDepth];
setupInitialStateStack();
/** Sending SM_INIT_CMD message to invoke enter methods asynchronously */
sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));// 不同于4.0.4,比如:在UI线程中,调用状态机的start方法,这里只是把SM_INIT_CMD消息发送给HandlerThread中的Handler处理,初始状态的enter、exit方法,都是在状态机的HandlerThread线程中执行的,不会占用UI线程的资源^-^算是一个小改进吧
if (mDbg) Log.d(TAG, "completeConstruction: X");
}
StateMachine:
/**
* Enqueue a message to the front of the queue for this state machine.
* Protected, may only be called by instances of StateMachine.
*/
protected final void sendMessageAtFrontOfQueue(int what, Object obj) {
mSmHandler.sendMessageAtFrontOfQueue(obtainMessage(what, obj));
}