Android StateMachine和AsyncChannelWord格式.docx
《Android StateMachine和AsyncChannelWord格式.docx》由会员分享,可在线阅读,更多相关《Android StateMachine和AsyncChannelWord格式.docx(27页珍藏版)》请在冰豆网上搜索。
∙*
∙*@paramnameofthestatemachine
∙*/
∙protectedStateMachine(Stringname){
∙mSmThread=newHandlerThread(name);
∙mSmThread.start();
∙Looperlooper=mSmThread.getLooper();
∙
∙initStateMachine(name,looper);
∙}
∙*ConstructorcreatesaStateMachineusingthelooper.
∙protectedStateMachine(Stringname,Looperlooper){
这里有两中构造方法,一是只传入StateMachine的名字,StateMachine自己构造HanderThread;
第二种是传入StateMachine的名字和一个looper,两种方法的区别在于处理的SmHandler将附在哪一个looper上面,后面我们将会看到这两种构造函数的使用。
接着看initStateMachine(name,looper)
∙privatevoidinitStateMachine(Stringname,Looperlooper){
∙mName=name;
∙mSmHandler=newSmHandler(looper,this);
下面我们以WifiStateMachine这个实例的来仔细分析StateMachine的创建以及运行,WifiStateMachine是继承与StateMachine,其创建过程在WifiService中,代码如下:
∙publicWifiService(Contextcontext){
∙mContext=context;
∙mInterfaceName=SystemProperties.get("
wifi.interface"
"
wlan0"
);
∙mWifiStateMachine=newWifiStateMachine(mContext,mInterfaceName);
∙mWifiStateMachine.enableRssiPolling(true);
∙.......
∙HandlerThreadwifiThread=newHandlerThread("
WifiService"
∙wifiThread.start();
∙mClientHandler=newClientHandler(wifiThread.getLooper());
∙mWifiStateMachineHandler=newWifiStateMachineHandler(wifiThread.getLooper());
∙mWifiController=newWifiController(mContext,this,wifiThread.getLooper());
∙mWifiController.start();
进入到WifiStateMachine的构造函数分析,code在framwork/base/wifi/java/android/net/wifi/WifiStateMachine.java
∙publicWifiStateMachine(Contextcontext,StringwlanInterface){
∙super("
WifiStateMachine"
∙mInterfaceName=wlanInterface;
∙mWifiNative=newWifiNative(mInterfaceName);
∙mWifiConfigStore=newWifiConfigStore(context,mWifiNative);
∙mWifiMonitor=newWifiMonitor(this,mWifiNative);
∙mWifiInfo=newWifiInfo();
∙mSupplicantStateTracker=newSupplicantStateTracker(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);
∙//startthestatemachine
∙start();
根据前面的StateMachine的构造函数,我们可以知道WifiStateMachine会新建一个HandlerThread,名字为“WifiStateMachine”,而在WifiService中创建的另一个对象WifiController将运行在WifiService本身创建的thread里,这些我们可以用DDMS去查看system_server这个进程的所有线程来确认:
接着看WifiStateMachine的构造函数,我们会看到很多的addState方法,进入到这个函数来分析:
∙*Addanewstatetothestatemachine
∙*@paramstatethestatetoadd
∙*@paramparenttheparentofstate
∙protectedfinalvoidaddState(Statestate,Stateparent){
∙mSmHandler.addState(state,parent);
∙*Addanewstatetothestatemachine,parentwillbenull
∙*@paramstatetoadd
∙protectedfinalvoidaddState(Statestate){
∙mSmHandler.addState(state,null);
一般来说,HSM只有会一个最上层的父亲State,其它所有的State都是其子State,这一点比较像多叉树。
addState只是简单的调用SmHander的addState方法,那我们进入到这个方法中分析:
∙privatefinalStateInfoaddState(Statestate,Stateparent){
∙if(mDbg){
∙mSm.log("
addStateInternal:
Estate="
+state.getName()+"
parent="
∙+((parent==null)?
"
"
:
parent.getName()));
∙}
∙StateInfoparentStateInfo=null;
∙if(parent!
=null){
∙parentStateInfo=mStateInfo.get(parent);
∙if(parentStateInfo==null){
∙//Recursivelyaddourparentasit'
snotbeenaddedyet.
∙parentStateInfo=addState(parent,null);
∙StateInfostateInfo=mStateInfo.get(state);
∙if(stateInfo==null){
∙stateInfo=newStateInfo();
∙mStateInfo.put(state,stateInfo);
∙//Validatethatwearen'
taddingthesamestateintwodifferenthierarchies.
∙if((stateInfo.parentStateInfo!
=null)
∙&
&
(stateInfo.parentStateInfo!
=parentStateInfo)){
∙thrownewRuntimeException("
statealreadyadded"
∙stateInfo.state=state;
∙stateInfo.parentStateInfo=parentStateInfo;
∙stateInfo.active=false;
∙if(mDbg)mSm.log("
XstateInfo:
+stateInfo);
∙returnstateInfo;
mStateInfo是一个HashMap,键是State,值为StateInfo,用于保存和查找StateMachine中所有的StateInfo,前面我们介绍过,StateInfo除了包含其自身State以外,还包含其父StateInfo,所以通过mStateInfo结构,我们可以很方便的从一个State找到其所有的父State,这在后面介绍的处理消息流程中非常重要。
我们接着来看addState方法,首先根据第二个参数parent是否为空来判断是否要将所有加入到mStateInfo的State的所有父State也加入进来,如果parent不为空,则先去mStateInfo中获取parentstate的StateInfo,如果没有查找到,说明这个父State还没有加入进来,则先递归的加入所有的父State;
如果parent为空或者所有的所有的父State已经全部进入进来了,则构造一个StateInfo并且对其state、parentStateInfo和active进行赋值,并把它加入到mStateInfo中。
当WifiStateMachine中所有的state全部加入到mStateInfo后,我们会看到这样一个树形结构:
在WifiStateMachine构造函数中添加完所有的state后,会调用setInitialState将InitialState设为初始状态,代码比较简单。
最后就调用start()方法,让WifiStateMachine运行起来。
这里的start()方法并不是新建一个thread之类的运行,而是根据InitialState去构建好从最上层State到InitialState这条分支上面的所有State信息,然后发送一个SM_INIT_CMD给SmHandler让其做初始化处理,来看代码:
∙*Startthestatemachine.
∙publicvoidstart(){
∙//mSmHandlercanbenullifthestatemachinehasquit.
∙SmHandlersmh=mSmHandler;
∙if(smh==null)return;
∙/**Sendthecompleteconstructionmessage*/
∙pleteConstruction();
∙/**
∙*Completetheconstructionofthestatemachine.
∙privatefinalvoidcompleteConstruction(){
completeConstruction:
E"
∙*Determinethemaximumdepthofthestatehierarchy
∙*sowecanallocatethestatestacks.
∙intmaxDepth=0;
∙for(StateInfosi:
mStateInfo.values()){
∙intdepth=0;
∙for(StateInfoi=si;
i!
=null;
depth++){
∙i=i.parentStateInfo;
∙if(maxDepth<
depth){
∙maxDepth=depth;
maxDepth="
+maxDepth);
∙mStateStack=newStateInfo[maxDepth];
∙mTempStateStack=newStateInfo[maxDepth];
∙setupInitialStateStack();
∙/**SendingSM_INIT_CMDmessagetoinvokeentermethodsasynchronously*/
∙sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD,mSmHandlerObj));
X"
start方法很简单,只是调用SmHandler的completeConstruction(),在这个函数中,首先计算mStateInfo中最大的深度,然后new两个数组,mStateStack和mTempStateStack用于保存处于活动状态分支上的所有State信息,上图中所示的WifiStateMachine的maxDepth=6。
接着来看setUpInitStateStack函数:
∙privatefinalvoidsetupInitialStateStack(){
setupInitialStateStack:
EmInitialState="
+mInitialState.getName());
∙StateInfocurStateInfo=mStateInfo.get(mInitialState);
∙for(mTempStateStackCount=0;
curStateInfo!
mTempStateStackCount++){
∙mTempStateStack[mTempStateStackCount]=curStateInfo;
∙curStateInfo=curStateInfo.parentStateInfo;
∙//EmptytheStateStack
∙mStateStackTopIndex=-1;
∙moveTempStateStackToStateStack();
setUpInitStateStack根据mStateInfo和mInitialState来填充从根State到mInitialState这条路径上所有的State到mTempStateStack中,以WifiStateMachine来举例,即mTempStateStack内容为:
0--InitialState,1--DefaultState。
接着来看moveTempStateStacktoStateStack():
∙privatefinalintmoveTempStateStackToStateStack(){
∙intstartingIndex