android状态机实现原理

从源代码角度去分析状态机的实现过程。

主要涉及到的文件有:

frameworks/base/wifi/java/android/net/wifi/WifiStateMachine.java

frameworks/base/core/java/com/android/internal/util/StateMachine.java

frameworks/base/core/java/com/android/internal/util/State.java

frameworks/base/core/java/com/android/internal/util/IState.java

其中IState是一个接口类:


上述的方法会由StateMachine来支配,决定何时调用,现有这个概念即可。


接着看StateMachine类中一些重要的内嵌类和函数。

[cpp]  view plain copy
  1.     public static class ProcessedMessageInfo {//包含一个状态的所有信息  
  2.         private int what;  
  3.         private State state;//这个经常用到,表示当前处于那个状态  
  4.         private State orgState;//表示接收到消息的状态  
  5. ........................................  
  6.         ProcessedMessageInfo(Message message, State state, State orgState) {  
  7.             update(message, state, orgState);//更新当前状态  
  8.         }  
  9. ..........................................  
  10.         public void update(Message message, State state, State orgState) {  
  11.             this.what = message.what;  
  12.             this.state = state;  
  13.             this.orgState = orgState;  
  14.         }  
  15. .......................................  
  16. }  


[cpp]  view plain copy
  1.     private static class ProcessedMessages {//保存最近处理的20条消息,具体包括state,发送的message等  
  2.   
  3.         private static final int DEFAULT_SIZE = 20;//默认的最大状态个数,这个不是指所有的状态,而是当前活动状态往父类追溯得到的所有类的状态  
  4.   
  5.         private Vector<ProcessedMessageInfo> mMessages = new Vector<ProcessedMessageInfo>();  
  6.         private int mMaxSize = DEFAULT_SIZE;  
  7. ....................................  
  8.         ProcessedMessageInfo get(int index) {//根据索引获取状态信息  
  9.             int nextIndex = mOldestIndex + index;  
  10.             if (nextIndex >= mMaxSize) {  
  11.                 nextIndex -= mMaxSize;  
  12.             }  
  13.             if (nextIndex >= size()) {  
  14.                 return null;  
  15.             } else {  
  16.                 return mMessages.get(nextIndex);  
  17.             }  
  18.         }  
  19. .........................................  
  20.         void add(Message message, State state, State orgState) {//orgState为最底层状态节点,state为有能力处理message的节点,他们可能相等,或则state为orgState的祖类节点  
  21.             mCount += 1;  
  22.             if (mMessages.size() < mMaxSize) {  
  23.                 mMessages.add(new ProcessedMessageInfo(message, state, orgState));  
  24.             } else {  
  25.                 ProcessedMessageInfo pmi = mMessages.get(mOldestIndex);  
  26.                 mOldestIndex += 1;  
  27.                 if (mOldestIndex >= mMaxSize) {  
  28.                     mOldestIndex = 0;  
  29.                 }  
  30.                 pmi.update(message, state, orgState);  
  31.             }  
  32.         }  
  33.     }  


[cpp]  view plain copy
  1. private static class SmHandler extends Handler {  
  2. .................................  
  3.         private StateInfo mStateStack[];//这里存放的是当前state以及父类的state  
  4.         private int mStateStackTopIndex = -1;//mStateStack数组的下标索引  
  5.         private StateInfo mTempStateStack[];//状态信息缓存区  
  6.         private HaltingState mHaltingState = new HaltingState();//状态挂起时候才会用到,一般用不上  
  7.         private QuittingState mQuittingState = new QuittingState();//状态退出时候才会用上,一般用不上  
  8.         private StateMachine mSm;//全局的StateMachine引用,在构造函数中this指针赋的值  
  9.         private HashMap<State, StateInfo> mStateInfo =  
  10.             new HashMap<State, StateInfo>();//保存所有加入的state信息  
  11.         private State mInitialState;//初始化的状态  
  12.         private State mDestState;//切换时新的目标状态  
  13.         @Override  
  14.         public final void handleMessage(Message msg) {  
  15.             processMsg(msg);//处理接收到的消息  
  16.             performTransitions();//处理就状态到新状态的切换  
  17.   
  18.             if (mDbg) Log.d(TAG, "handleMessage: X");  
  19.         }  
  20. ..........................  
  21. }  


到这里,还是先把wifistatemachine的状态图写出来,以便好理解。




比如,如果当前状态为mDriverFailedState,则上面mStateStack存放的是[mDefaultState,mDriverUnloadedState,mDriverFailedState]三个状态的信息


StateMachine的构造函数做了些什么?

[cpp]  view plain copy
  1. protected StateMachine(String name) {  
  2.     mSmThread = new HandlerThread(name);  
  3.     mSmThread.start();  
  4.     Looper looper = mSmThread.getLooper();  
  5.   
  6.     initStateMachine(name, looper);  
  7. }    

而在initStateMachine方法中:

[cpp]  view plain copy
  1. private void initStateMachine(String name, Looper looper) {  
  2.     mName = name;  
  3.     mSmHandler = new SmHandler(looper, this); //mSmHandler是一个全局的handler,后面常用到                                                                                                               
  4. }  

[cpp]  view plain copy
  1. private SmHandler(Looper looper, StateMachine sm) {                                                                                                      
  2.     super(looper);  
  3.     mSm = sm;//mSm是一个全局的变量,后面经常用到  
  4.   
  5.     addState(mHaltingState, null);//状态挂起的时候调用  
  6.     addState(mQuittingState, null);//状态退出的时候调用  
  7. }  

WifiStateMachine的构造函数主要做了些什么?

主要是调用addState方法将wifi中创建的状态加入状态机中,最后setInitialState来设置初始化状态。具体过程如下:

[cpp]  view plain copy
  1. protected final void addState(State state, State parent) {//将state添加到父节点parent下,如果parent为null,则state作为父节点  
  2.     mSmHandler.addState(state, parent);                                                                                                                      
  3. }   

[cpp]  view plain copy
  1. private final StateInfo addState(State state, State parent) {  
  2.     if (mDbg) {  
  3.         Log.d(TAG, "addStateInternal: E state=" + state.getName()  
  4.                 + ",parent=" + ((parent == null) ? "" : parent.getName()));  
  5.     }  
  6.     StateInfo parentStateInfo = null;  
  7.     if (parent != null) {  
  8.         parentStateInfo = mStateInfo.get(parent);//取出父节点的parentStateInfo信息  
  9.         if (parentStateInfo == null) { //如果父节点为null,则递归调用,把当前节点作为父节点                                                                 
  10.             // Recursively add our parent as it's not been added yet.  
  11.             parentStateInfo = addState(parent, null);  
  12.         }  
  13.     }  
  14.     StateInfo stateInfo = mStateInfo.get(state);//新节点,肯定为null了  
  15.     if (stateInfo == null) {  
  16.         stateInfo = new StateInfo();  
  17.         mStateInfo.put(state, stateInfo);//将state和stateInfo放入哈系表中,以后根据state即可取出stateInfo信息,前面说过,全局变量mStateInfo哈系表保存了所有state信息  
  18.     }  
  19.   
  20.     // Validate that we aren't adding the same state in two different hierarchies.  
  21.     if ((stateInfo.parentStateInfo != null) &&   //新创建还没有赋值,肯定为null啦,否则就抛出异常了  
  22.             (stateInfo.parentStateInfo != parentStateInfo)) {  
  23.             throw new RuntimeException("state already added");  
  24.     }  
  25.     stateInfo.state = state;  
  26.     stateInfo.parentStateInfo = parentStateInfo;//以后通过state可以找到父节点,一直递归,如果state的父节点为null,则表示到了顶部  
  27.     stateInfo.active = false//时候是当前活动状态标志  
  28.     if (mDbg) Log.d(TAG, "addStateInternal: X stateInfo: " + stateInfo);  
  29.     return stateInfo;  
  30. }  

这样,通过上面的addState方法,最终形成了上图所示的树形结构。在使用之前,还要设置state的初始化状态:

[cpp]  view plain copy
  1. /**   
  2.  * Set the initial state. This must be invoked before 
  3.  * and messages are sent to the state machine. 
  4.  * 
  5.  * @param initialState is the state which will receive the first message. 
  6.  */  
  7. protected final void setInitialState(State initialState) {                                                                                                   
  8.     mSmHandler.setInitialState(initialState);  
  9. }    

注释已经说的很清楚,这是第一次接收到消息时候进入的状态:

[cpp]  view plain copy
  1. private final void setInitialState(State initialState) {                                                                                                 
  2.     if (mDbg) Log.d(TAG, "setInitialState: initialState" + initialState.getName());  
  3.     mInitialState = initialState;//先简单的保存到全局变量中,后续才用到  
  4. }  

这样初始化工作完成,WifiStateMachine的构造函数最后调用start()来启动状态机,它的实现方法在父类StateMachine中:

[cpp]  view plain copy
  1.     public void start() {                                                                                                                                        
  2.         // mSmHandler can be null if the state machine has quit.  
  3.         if (mSmHandler == null) return;//mSmHandler引用在前面构造函数中就赋值了,肯定不为null了  
  4.   
  5.         /** Send the complete construction message */  
  6.         mSmHandler.completeConstruction();  
  7.     }  
  8. }  

来看completeConstruction方法的实现:

[cpp]  view plain copy
  1. private final void completeConstruction() {  
  2.     if (mDbg) Log.d(TAG, "completeConstruction: E");  
  3.   
  4.     /** 
  5.      * Determine the maximum depth of the state hierarchy 
  6.      * so we can allocate the state stacks. 
  7.      */  
  8.     int maxDepth = 0;   
  9.     for (StateInfo si : mStateInfo.values()) {//这个for循环就是遍历前面添加到哈系表中的状态,找出树的最大深度,根据前面的树形表可以看出,最大深度为5  
  10.         int depth = 0;   
  11.         for (StateInfo i = si; i != null; depth++) {  
  12.             i = i.parentStateInfo;  
  13.         }      
  14.         if (maxDepth < depth) {  
  15.             maxDepth = depth;                                                                                                                            
  16.         }      
  17.     }      
  18.     if (mDbg) Log.d(TAG, "completeConstruction: maxDepth=" + maxDepth);  
  19.   
  20.     mStateStack = new StateInfo[maxDepth];//这个是最后存放当前活动state的,可以看到要得到最大深度的作用就是为了创建数组,因为当前活动state以及父类家族最多就为maxDepth  
  21.     mTempStateStack = new StateInfo[maxDepth];//这个是暂时存放state的  
  22.     setupInitialStateStack();  
  23.   
  24.     /**   
  25.      * Construction is complete call all enter methods 
  26.      * starting at the first entry. 
  27.      */  
  28.     mIsConstructionCompleted = true;  
  29.     mMsg = obtainMessage(SM_INIT_CMD);  
  30.     invokeEnterMethods(0);  
  31.   
  32.     /**   
  33.      * Perform any transitions requested by the enter methods 
  34.      */  
  35.     performTransitions();  
  36.   
  37.     if (mDbg) Log.d(TAG, "completeConstruction: X");  
  38. }  

接着下一句是setupInitialStateStack方法:

[cpp]  view plain copy
  1. private final void setupInitialStateStack() {                                                                                                            
  2.     if (mDbg) {  
  3.         Log.d(TAG, "setupInitialStateStack: E mInitialState="  
  4.             + mInitialState.getName());  
  5.     }  
  6.   
  7.     StateInfo curStateInfo = mStateInfo.get(mInitialState);//取出初始化state,前面已经赋值过,这里为WifiStateMachine中mInitialState对应的stateInfo  
  8.     for (mTempStateStackCount = 0; curStateInfo != null; mTempStateStackCount++) {  
  9.         mTempStateStack[mTempStateStackCount] = curStateInfo;//最后mTempStateStack存放的值为[mInitialState,mDefaultState]对应的stateInfo  
  10.         curStateInfo = curStateInfo.parentStateInfo;  
  11.     }  
  12.   
  13.     // Empty the StateStack  
  14.     mStateStackTopIndex = -1;  
  15.   
  16.     moveTempStateStackToStateStack();  
  17. }  

moveTempStateStackToStateStack方法就是将mTempStateStack的值倒序放到mStateStack中:

[cpp]  view plain copy
  1. private final int moveTempStateStackToStateStack() {                                                                                                     
  2.     int startingIndex = mStateStackTopIndex + 1;// -1 + 1 = 0;  
  3.     int i = mTempStateStackCount - 1;//第一次进入,2 - 1 = 1;  
  4.     int j = startingIndex;  
  5.     while (i >= 0) {  
  6.         if (mDbg) Log.d(TAG, "moveTempStackToStateStack: i=" + i + ",j=" + j);  
  7.         mStateStack[j] = mTempStateStack[i];  
  8.         j += 1;  
  9.         i -= 1;  
  10.     }  
  11.   
  12.     mStateStackTopIndex = j - 1;// 2 - 1 = 1  
  13.     if (mDbg) {  
  14.         Log.d(TAG, "moveTempStackToStateStack: X mStateStackTop="  
  15.               + mStateStackTopIndex + ",startingIndex=" + startingIndex  
  16.               + ",Top=" + mStateStack[mStateStackTopIndex].state.getName());  
  17.     }  
  18.     return startingIndex; //0  
  19. }  
这样,当前状态信息就保存在mStateStack中,为[mDefaultState, mInitialState]对应的状态信息。

回到completeConstruction中,接着invokeEnterMethods方法:

[cpp]  view plain copy
  1. private final void invokeEnterMethods(int stateStackEnteringIndex) {                                                                                     
  2.     for (int i = stateStackEnteringIndex; i <= mStateStackTopIndex; i++) {//前面分析可以,mStateStackTopIndex为1  
  3.         if (mDbg) Log.d(TAG, "invokeEnterMethods: " + mStateStack[i].state.getName());  
  4.         mStateStack[i].state.enter();//依次调用活动状态的enter方法,可以看到是从最顶层父类依次往下调用的  
  5.         mStateStack[i].active = true//把当前state置为true  
  6.     }  
  7. }  


mDefaultState重写enter方法,父类State的enter方法什么也不做;InitialState有重写enter方法:

[cpp]  view plain copy
  1. class InitialState extends State {  
  2.     @Override  
  3.     //TODO: could move logging into a common class  
  4.     public void enter() {  
  5.            ......................................  
  6.   
  7.         if (WifiNative.isDriverLoaded()) {  
  8.             transitionTo(mDriverLoadedState);//如果我们打开过wifi,状态就会切换到mDriverLoadedState去了  
  9.         }      
  10.         else {  
  11.             transitionTo(mDriverUnloadedState);//第一次打开是没有load过的,所以进入unload状态  
  12.         }      
  13.   
  14.            .................................  
  15.     }  
  16. }  


[cpp]  view plain copy
  1. protected final void transitionTo(IState destState) {//IState是所有state的接口类  
  2.     mSmHandler.transitionTo(destState);调用handler方法来处理  
  3. }    

[cpp]  view plain copy
  1. private final void transitionTo(IState destState) {  
  2.     mDestState = (State) destState;//先保存到变量中,后续真正状态切换时候才用到  
  3.     if (mDbg) Log.d(TAG, "StateMachine.transitionTo EX destState" + mDestState.getName());                                                               
  4. }  

这样invokeEnterMethods方法就完成了,接着是performTransitions方法,这是真正处理状态切换的方法了:

[cpp]  view plain copy
  1. private void performTransitions() {  
  2.     .....................  
  3.     State destState = null;  
  4.     while (mDestState != null) {  
  5.         ......................................  
  6.         destState = mDestState;//destState为mDriverUnLoadedState  
  7.         mDestState = null;  
  8.         ..............................  
  9.         StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);                                                                     
  10.         invokeExitMethods(commonStateInfo);  
  11.         int stateStackEnteringIndex = moveTempStateStackToStateStack();  
  12.         invokeEnterMethods(stateStackEnteringIndex);  
  13.   
  14.   
  15.         moveDeferredMessageAtFrontOfQueue();  
  16.     }     
  17.     if (destState != null) {  
  18.         if (destState == mQuittingState) {  
  19.             cleanupAfterQuitting();  
  20.   
  21.         } else if (destState == mHaltingState) {  
  22.   
  23.             mSm.halting();  
  24.         }  
  25.     }  
  26. }  



setupTempStateStackWithStatesToEnter方法主要是把当前活动state家族放入mTempStateStack中,并且返回顶层节点的信息,这样,mTempStateStack保存信息为[mDriverUnLoadedState, mDefaultState]的信息;

invokeExitMethods方法则是从当前活动state顶层节点一次调用exit方法,并且设置state的active标记为false;这里要注意当前活动的还是是mStateStack中的信息,即[mDefaultState, mInitialState]对应的状态信息,exit方法一般是做一些善后工作。处理完成后

mStateStackTopIndex又自减为-1。

moveTempStateStackToStateStack和invokeEnterMethods方法前面已经分析过。完成后mStateStack的状态信息变为[mDefaultState,mDriverUnLoadedState]

最后一个函数moveDeferredMessageAtFrontOfQueue刷新消息队列的排序。该方法就是将mDeferredMessages容器中的消息按先后顺序发送出去,然后清空容器。至于消息是如何加入容器的,后面遇到再分析。

这样start方法就完成,整个WifiStateMachine构造函数也建立完成了。


如果我们打开wifi,会在WifiService中调用setWifiEnabled - >mWifiStateMachine.setWifiEnabled来启动。setWifiEnabled的状态切换过程为:

[cpp]  view plain copy
  1. public void setWifiEnabled(boolean enable) {                                                                                                                 
  2.     mLastEnableUid.set(Binder.getCallingUid());  
  3.     if (enable) {  
  4.         /* Argument is the state that is entered prior to load */  
  5.         sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));  
  6.         sendMessage(CMD_START_SUPPLICANT);  
  7.     } else {  
  8.         sendMessage(CMD_STOP_SUPPLICANT);  
  9.         /* Argument is the state that is entered upon success */  
  10.         sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_STATE_DISABLED, 0));  
  11.     }  
  12. }  
sendMessage方法是StateMachine实现的,它封装了Handler类的sendMessage方法,会被SmHandler类的handleMessage来接收处理。而它是调用一下两个方法来处理消息的:

[cpp]  view plain copy
  1. processMsg(msg);  
  2. performTransitions();  
先看第一个:

[cpp]  view plain copy
  1. private final void processMsg(Message msg) {  
  2.     StateInfo curStateInfo = mStateStack[mStateStackTopIndex];//mStateStack保存信息的顺序为顶层节点->底层节点,mStateStackTopIndex为数组个数,这里取出的就为最底层节点的状态信息  
  3.     if (mDbg) {  
  4.         Log.d(TAG, "processMsg: " + curStateInfo.state.getName());  
  5.     }  
  6.     while (!curStateInfo.state.processMessage(msg)) {//所以从底层节点开始往上遍历,调用processMessage来处理消息,直到找到一个可以处理的节点后返回HANDLED(true),条件退出  
  7.         /** 
  8.          * Not processed 
  9.          */                                                                                                                                              
  10.         curStateInfo = curStateInfo.parentStateInfo;  
  11.         if (curStateInfo == null) {//找到顶层节点了,才用unhandledMessage,它不做什么事情,打印一句LOG信息而已  
  12.             /** 
  13.              * No parents left so it's not handled 
  14.              */  
  15.             mSm.unhandledMessage(msg);  
  16.             if (isQuit(msg)) {//如果命令是SM_QUIT_CMD才会退出,一般情况下是不会退出的  
  17.                 transitionTo(mQuittingState);  
  18.             }  
  19.             break;  
  20.         }  
  21.         if (mDbg) {  
  22.             Log.d(TAG, "processMsg: " + curStateInfo.state.getName());  
  23.         }  
  24.     }  
  25.   
  26.     /** 
  27.      * Record that we processed the message 
  28.      */  
  29.     if (curStateInfo != null) {  
  30.         State orgState = mStateStack[mStateStackTopIndex].state;  
  31.         mProcessedMessages.add(msg, curStateInfo.state, orgState);//保存处理processMessage的消息到mProcessedMessages中,作为一个记录,一般保存最近的20条,这个最大值可以自己定义  
  32.     } else {  
  33.         mProcessedMessages.add(msg, null, null);  
  34.     }  
  35. }  

这时mStateStack的状态信息变为[mDefaultState, mDriverUnLoadedState],先所以调用mDriverUnLoadedState的processMessage方法,而前面发送的消息为:

[cpp]  view plain copy
  1. sendMessage(obtainMessage(CMD_LOAD_DRIVER, WIFI_STATE_ENABLING, 0));  
  2. sendMessage(CMD_START_SUPPLICANT);  

第一句的CMD_LOAD_DRIVER,发送给应用层的消息为WIFI_STATE_ENABLING:

[cpp]  view plain copy
  1. class DriverUnloadedState extends State {                                                                                                                    
  2.     @Override  
  3.     public void enter() {  
  4.         if (DBG) log(getName() + "\n");  
  5.         EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());  
  6.     }  
  7.     @Override  
  8.     public boolean processMessage(Message message) {  
  9.         if (DBG) log(getName() + message.toString() + "\n");  
  10.         switch (message.what) {  
  11.             case CMD_LOAD_DRIVER:  
  12.                 mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING);//这是发送消息给WifiP2pService,WifiP2pService会响应并返回消息WIFI_ENABLE_PROCEED,其中过程有点复杂,后续再分析  
  13.                 transitionTo(mWaitForP2pDisableState);//状态切换到了mWaitForP2pDisableState,其他好像没有做什么  
  14.                 break;  
  15.             case WifiP2pService.P2P_ENABLE_PENDING:  
  16.                 mReplyChannel.replyToMessage(message, P2P_ENABLE_PROCEED);  
  17.                 break;  
  18.             default:  
  19.                 return NOT_HANDLED;  
  20.         }  
  21.         EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);  
  22.         return HANDLED;  
  23.     }  
  24. }  
WaitForP2pDisableState的enter做什么了?

状态已经进入mWaitForP2pDisableState中了:

[cpp]  view plain copy
  1. class WaitForP2pDisableState extends State {  
  2.     .............................  
  3.     @Override  
  4.     public boolean processMessage(Message message) {  
  5.             case WifiP2pService.WIFI_ENABLE_PROCEED: //响应WifiP2pService消息                                                                                                        
  6.                 //restore argument from original message (CMD_LOAD_DRIVER)  
  7.                 message.arg1 = mSavedArg;  
  8.                 transitionTo(mDriverLoadingState);  
  9.                 break;  
  10.             case CMD_LOAD_DRIVER:  
  11.             case CMD_UNLOAD_DRIVER:  
  12.             case CMD_START_SUPPLICANT:  
  13.            ..........................  
  14.                 deferMessage(message);  
  15.            .............................  


deferMessage将消息放入mDeferredMessages容器中,前面有提及过,作用是要把消息保存起来,等切换到下一个状态后,再将消息发送出去,让下一个状态接收;接下来的performTransitions方法中会将消息发送出去,并且在切换下一个状态前清空容器。

这时候状态在WaitForP2pDisableState中,WifiP2pService接收到消息WIFI_ENABLE_PENDING后,返回WIFI_ENABLE_PROCEED作为响应;

所以执行transitionTo(mDriverLoadingState)进入下一个状态。

processMsg就处理完成了,接着的performTransitions前面已经分析过,主要工作为调用当前状态的exit方法;切换新状态到mSupplicantStartingState,并调用新状态的enter方法,静等下一个消息的到来。

根据前面的分析可知,这时候先执行的是mDriverLoadingState的enter方法:

[cpp]  view plain copy
  1. class DriverLoadingState extends State {  
  2.     @Override  
  3.     public void enter() {  
  4.         if (DBG) log(getName() + "\n");  
  5.         EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());  
  6.   
  7.         final Message message = new Message();  
  8.         message.copyFrom(getCurrentMessage());  
  9.         /* TODO: add a timeout to fail when driver load is hung. 
  10.          * Similarly for driver unload. 
  11.          */  
  12.         new Thread(new Runnable() {  
  13.             public void run() {  
  14.                 mWakeLock.acquire();  
  15.                 //enabling state  
  16.                 switch(message.arg1) {  
  17.                     case WIFI_STATE_ENABLING:  
  18.                         setWifiState(WIFI_STATE_ENABLING);  
  19.                         break;  
  20.                 if(WifiNative.loadDriver()) {  
  21.                     if (DBG) log("Driver load successful");  
  22.                     sendMessage(CMD_LOAD_DRIVER_SUCCESS);  
  23.                 } else {  
  24.                     loge("Failed to load driver!");                                                                                                          
  25.                     switch(message.arg1) {  
  26.                         case WIFI_STATE_ENABLING:  
  27.                             setWifiState(WIFI_STATE_UNKNOWN);  
  28.                             break;  
  29.                         case WIFI_AP_STATE_ENABLING:  
  30.                             setWifiApState(WIFI_AP_STATE_FAILED);  
  31.                             break;  
  32.                     }  
  33.                     sendMessage(CMD_LOAD_DRIVER_FAILURE);  
  34.                 }  
  35.                 mWakeLock.release();  
  36.             }  
  37.         }).start();  
  38.   
  39.     @Override  
  40.     public boolean processMessage(Message message) {  
  41.         if (DBG) log(getName() + message.toString() + "\n");  
  42.         switch (message.what) {  
  43.             case CMD_LOAD_DRIVER_SUCCESS:  
  44.                 transitionTo(mDriverLoadedState);  
  45.                 break;  
  46.             case CMD_LOAD_DRIVER_FAILURE:  
  47.                 transitionTo(mDriverFailedState);  
  48.                 break;  
  49.             case CMD_LOAD_DRIVER:  
  50.             case CMD_UNLOAD_DRIVER:  
  51.             case CMD_START_SUPPLICANT:  
  52.             case CMD_STOP_SUPPLICANT:  
  53.             case CMD_START_AP:  
  54.             case CMD_STOP_AP:  
  55.             case CMD_START_DRIVER:  
  56.             case CMD_STOP_DRIVER:  
  57.             case CMD_SET_SCAN_MODE:  
  58.             case CMD_SET_SCAN_TYPE:  
  59.             case CMD_SET_HIGH_PERF_MODE:  
  60.             case CMD_SET_COUNTRY_CODE:  
  61.             case CMD_SET_FREQUENCY_BAND:  
  62.             case CMD_START_PACKET_FILTERING:  
  63.             case CMD_STOP_PACKET_FILTERING:  
  64.                 deferMessage(message);  
  65.                 break;  
  66.             default:  
  67.                 return NOT_HANDLED;  
  68.         }  
  69.         EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);  
  70.         return HANDLED;  
  71.     }  

enter线程中的消息为前面发送的WIFI_STATE_ENABLING,setWifiState的作用是发送广播通知应用层wifi状态的改变,并且加载JNI的wifi驱动,成功后还发送CMD_LOAD_DRIVER_SUCCESS消息。

接着第二句命令CMD_START_SUPPLICANT,状态在mDriverLoadingState中,执行processMessage方法,这时候会先接收前面的延时消息CMD_LOAD_DRIVER_SUCCESS,接着接收CMD_LOAD_DRIVER,CMD_START_SUPPLICANT

状态就切换到了mDriverLoadedState,并且将其他两条消息延后再传给下一个状态。


后续WifiService会根据逻辑需求,发送各种命令过来进行状态的切换,但流程都和上述分析的一样,状态机能确保各种状态有条不紊的切换并保持控制流程的清晰明了。

最后画一幅流程图如下:






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值