Android StateMachine和AsyncChannel

在学习Android Wifi的code时,到处可以看到StateMachie和AsyncChannel的影子,这里我们先大致分析一下它们两个的原理。

StateMachine原理分析

顾名思义,StateMachine就是状态机的意思,从Goolge给出的解释:The state machine defined here is a hierarchical state machine which processes messages and can have states arranged hierarchically. 在Android世界里,StateMachine也叫做层次状态机,简称HSM,这里的HSM主要用来处理消息并且分层次管理其状态。引入HSM的原因是因为如果在代码当中写入很多swith…case..的语句,会比较难于管理其状态,并且代码也会写的比较复杂。而HSM并不是直接把message交友其本身来处理,而是传递给其State去处理,这样它本身就不必有任何改变,并且各个State直接还可以存在父子等关系,在处理消息的机制上面可以像面向对象的语言一样,父State定义一些基本的处理,子State去细化不同的实现,减少代码的冗余度。

先来看一下HSM的架构图:

从图中我们可以看到State和StateMachie两个大类,StateMachine主要依靠SmHandler去完成消息的分发与处理,在SmHandler中通过mStateStack[]来维持各个State直接的层次关系,而State只定义了简单的几个方法,如enter()、exit()、processMessage()等,分别用来表示刚进入这个状态、退出这个状态以及在这个状态中处理消息。在构建StateMachine时,会把一个个State通过addState()方法加入到mStateInfo中来,通过StateInfo的结构我们可以看出,每个StateInfo不仅包含其自身State,并且也会包含其父State,并且还有active这样变量来表示这个状态是否处于可见状态,这样SmHandler就可以通过mStateStack和mStateInfo来找到当前处于顶端的State,并调用其processMessage()方法,我们稍后会来介绍这样。先进入到StateMachine的构造函数看一下:

/*** Constructor creates a StateMachine with its own thread.** @param name of the state machine*/protected StateMachine(String name) {mSmThread = new HandlerThread(name);mSmThread.start();Looper looper = mSmThread.getLooper();initStateMachine(name, looper);}/*** Constructor creates a StateMachine using the looper.** @param name of the state machine*/protected StateMachine(String name, Looper looper) {initStateMachine(name, looper);}这里有两中构造方法,一是只传入StateMachine的名字,StateMachine自己构造HanderThread;第二种是传入StateMachine的名字和一个looper,两种方法的区别在于处理的SmHandler将附在哪一个looper上面,后面我们将会看到这两种构造函数的使用。接着看 looper) private void initStateMachine(String name, Looper looper) {mName = name;mSmHandler = new SmHandler(looper, this);}下面我们以WifiStateMachine这个实例的来仔细分析StateMachine的创建以及运行,WifiStateMachine是继承与StateMachine,其创建过程在WifiService中,代码如下: public WifiService(Context context) {mContext = context;mInterfaceName = SystemProperties.get("wifi.interface", "wlan0");mWifiStateMachine = new WifiStateMachine(mContext, mInterfaceName);mWifiStateMachine.enableRssiPolling(true);…….HandlerThread wifiThread = new HandlerThread("WifiService");wifiThread.start();mClientHandler = new ClientHandler(wifiThread.getLooper());mWifiStateMachineHandler = new WifiStateMachineHandler(wifiThread.getLooper());mWifiController = new WifiController(mContext, this, wifiThread.getLooper());mWifiController.start();

进入到WifiStateMachine的构造函数分析,code在framwork/base/wifi/java/android/net/wifi/WifiStateMachine.java

public WifiStateMachine(Context context, String wlanInterface) {super("WifiStateMachine");mContext = context;mInterfaceName = wlanInterface;…….mWifiNative = new WifiNative(mInterfaceName);mWifiConfigStore = new WifiConfigStore(context, mWifiNative);mWifiMonitor = new WifiMonitor(this, mWifiNative);mWifiInfo = new WifiInfo();mSupplicantStateTracker = new SupplicantStateTracker(context, this, mWifiConfigStore,getHandler());…….addState(mDefaultState);addState(mInitialState, mDefaultState);addState(mSupplicantStartingState, mDefaultState);addState(mSupplicantStartedState, mDefaultState);addState(mDriverStartingState, mSupplicantStartedState);addState(mDriverStartedState, mSupplicantStartedState);addState(mScanModeState, mDriverStartedState);addState(mConnectModeState, mDriverStartedState);addState(mL2ConnectedState, mConnectModeState);addState(mObtainingIpState, mL2ConnectedState);addState(mVerifyingLinkState, mL2ConnectedState);addState(mCaptivePortalCheckState, mL2ConnectedState);addState(mConnectedState, mL2ConnectedState);addState(mDisconnectingState, mConnectModeState);addState(mDisconnectedState, mConnectModeState);addState(mWpsRunningState, mConnectModeState);addState(mWaitForP2pDisableState, mSupplicantStartedState);addState(mDriverStoppingState, mSupplicantStartedState);addState(mDriverStoppedState, mSupplicantStartedState);addState(mSupplicantStoppingState, mDefaultState);addState(mSoftApStartingState, mDefaultState);addState(mSoftApStartedState, mDefaultState);addState(mTetheringState, mSoftApStartedState);addState(mTetheredState, mSoftApStartedState);addState(mUntetheringState, mSoftApStartedState);setInitialState(mInitialState);setLogRecSize(2000);setLogOnlyTransitions(false);if (DBG) setDbg(true);//start the state machinestart();…….}根据前面的StateMachine的构造函数,我们可以知道WifiStateMachine会新建一个HandlerThread,名字为“WifiStateMachine”,而在WifiService中创建的另一个对象WifiController将运行在WifiService本身创建的thread里,这些我们可以用DDMS去查看system_server这个进程的所有线程来确认:没有早一步,也没有晚一步,刚好遇上了你!

Android StateMachine和AsyncChannel

相关文章:

你感兴趣的文章:

标签云: