Android StateMachine和AsyncChannel.docx
- 文档编号:7406901
- 上传时间:2023-05-11
- 格式:DOCX
- 页数:27
- 大小:304.60KB
Android StateMachine和AsyncChannel.docx
《Android StateMachine和AsyncChannel.docx》由会员分享,可在线阅读,更多相关《Android StateMachine和AsyncChannel.docx(27页珍藏版)》请在冰点文库上搜索。
AndroidStateMachine和AsyncChannel
AndroidStateMachine和AsyncChannel
目录(?
)[-]
∙StateMachine原理分析
∙AsyncChannel分析
1双向通信连接的建立
1单向通信连接的建立
1
1
在学习AndroidWifi的code时,到处可以看到StateMachie和AsyncChannel的影子,这里我们先大致分析一下它们两个的原理。
StateMachine原理分析
顾名思义,StateMachine就是状态机的意思,从Goolge给出的解释:
Thestatemachinedefinedhereisahierarchicalstatemachinewhichprocessesmessagesandcanhavestatesarrangedhierarchically.在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的构造函数看一下:
∙/**
∙*ConstructorcreatesaStateMachinewithitsownthread.
∙*
∙*@paramnameofthestatemachine
∙*/
∙protectedStateMachine(Stringname){
∙mSmThread=newHandlerThread(name);
∙mSmThread.start();
∙Looperlooper=mSmThread.getLooper();
∙
∙initStateMachine(name,looper);
∙}
∙
∙/**
∙*ConstructorcreatesaStateMachineusingthelooper.
∙*
∙*@paramnameofthestatemachine
∙*/
∙protectedStateMachine(Stringname,Looperlooper){
∙initStateMachine(name,looper);
∙}
这里有两中构造方法,一是只传入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");
∙mContext=context;
∙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("addStateInternal:
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(){
∙if(mDbg)mSm.log("completeConstruction:
E");
∙
∙/**
∙*Determinethemaximumdepthofthestatehierarchy
∙*sowecanallocatethestatestacks.
∙*/
∙intmaxDepth=0;
∙for(StateInfosi:
mStateInfo.values()){
∙intdepth=0;
∙for(StateInfoi=si;i!
=null;depth++){
∙i=i.parentStateInfo;
∙}
∙if(maxDepth ∙maxDepth=depth; ∙} ∙} ∙if(mDbg)mSm.log("completeConstruction: maxDepth="+maxDepth); ∙ ∙mStateStack=newStateInfo[maxDepth]; ∙mTempStateStack=newStateInfo[maxDepth]; ∙setupInitialStateStack(); ∙ ∙/**SendingSM_INIT_CMDmessagetoinvokeentermethodsasynchronously*/ ∙sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD,mSmHandlerObj)); ∙ ∙if(mDbg)mSm.log("completeConstruction: X"); ∙} start方法很简单,只是调用SmHandler的completeConstruction(),在这个函数中,首先计算mStateInfo中最大的深度,然后new两个数组,mStateStack和mTempStateStack用于保存处于活动状态分支上的所有State信息,上图中所示的WifiStateMachine的maxDepth=6。 接着来看setUpInitStateStack函数: ∙privatefinalvoidsetupInitialStateStack(){ ∙if(mDbg){ ∙mSm.log("setupInitialStateStack: EmInitialState="+mInitialState.getName()); ∙} ∙ ∙StateInfocurStateInfo=mStateInfo.get(mInitialState); ∙for(mTempStateStackCount=0;curStateInfo! =null;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
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android StateMachine和AsyncChannel StateMachine AsyncChannel
![提示](https://static.bingdoc.com/images/bang_tan.gif)