安卓StateMachine分析举例---WifiStateMachine

WifiStateMachine创建:

创建在构造方法WifiStateMachine(Context context, String wlanInterface) 中实施:

public WifiStateMachine(Context context, String wlanInterface) {
     /*调用stateMachine类的构造方法完成状态机的构造,名字为WifiStateMachine*/
     super("WifiStateMachine");
     /*添加状态*/
     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);

     /*开始状态机*/
     start();

}

在start方法中,调用completeConstruction方法完成构造,这个方法之前已经分析过,主要是完成状态机棧的搭建,并发送启动完成的消息,将状态机运行起来。状态机起来后,分别运行mDefaultState和mInitialState的状态的enter方法,在mDefaultState的方法中do nothing,在mInitialState的enter方法中,进行了wifi相关的初始化,这里不做关注:

public void enter() {
    mWifiNative.unloadDriver();
    if (mWifiP2pChannel == null) {
       mWifiP2pChannel = new AsyncChannel();
       mWifiP2pChannel.connect(mContext, getHandler(), mWifiP2pManager.getMessenger());
    }

    if (mWifiApConfigChannel == null) {
        mWifiApConfigChannel = new AsyncChannel();
        WifiApConfigStore wifiApConfigStore = WifiApConfigStore.makeWifiApConfigStore(
                        mContext, getHandler());
        wifiApConfigStore.loadApConfiguration();
        mWifiApConfigChannel.connectSync(mContext, getHandler(),wifiApConfigStore.getMessenger());
    }
}

至此WifiStateMachine创建成功,运行在InitialState状态,罗列一下各个状态之间的关系:
这里写图片描述

WifiStateMachine状态切换举例–开启AP:

调用setHostApRunning方法,开启AP功能,此方法发送CMD_START_AP消息
状态机启动后处于InitialState状态,收到CMD_START_AP消息后:

 public boolean processMessage(Message message) {
      switch (message.what) {
       /*省略代码*/
       case CMD_START_AP:
            if (mWifiNative.loadDriver()) {
                /*设置AP状态*/
                setWifiApState(WIFI_AP_STATE_ENABLING);
                /*状态切换mSoftApStartingState*/
                transitionTo(mSoftApStartingState);
            } else {
                loge("Failed to load driver for softap");
            }
            /*省略代码*/
      }
 }

此消息处理函数处理完后,跳转到mSoftApStartingState
进入mSoftApStartingState的enter方法:

public void enter() {
    final Message message = getCurrentMessage();
    if (message.what == CMD_START_AP) {
        final WifiConfiguration config = (WifiConfiguration) message.obj;

        if (config == null) {
            mWifiApConfigChannel.sendMessage(CMD_REQUEST_AP_CONFIG);
        } else {
            mWifiApConfigChannel.sendMessage(CMD_SET_AP_CONFIG, config);
            /*开启AP*/
            startSoftApWithConfig(config);
        }
    } else {
        throw new RuntimeException("Illegal transition to SoftApStartingState: " + message);
    }
}

startSoftApWithConfig开启AP成功后,会发送CMD_START_AP_SUCCESS消息,
SoftApStartingState状态下,处理此消息:

public boolean processMessage(Message message) {
    switch(message.what) {
        //
         case CMD_START_AP_SUCCESS:
            /*设置AP状态*/
            setWifiApState(WIFI_AP_STATE_ENABLED);
            /*跳转到mSoftApStartedState*/
            transitionTo(mSoftApStartedState);
            break;
    }
}

CMD_START_AP_SUCCESS消息处理完后,跳转到mSoftApStartedState状态,执行该状态的enter方法。此状态下受到CMD_TETHER_STATE_CHANGE消息后处理:

public boolean processMessage(Message message) {
switch(message.what) {
        //
         case CMD_TETHER_STATE_CHANGE:
             TetherStateChange stateChange = (TetherStateChange) message.obj;
             /*开启tethering*/
            if (startTethering(stateChange.available)) {
                transitionTo(mTetheringState);
            }
            break;
    }
}

开启startTethering成功后,跳转到mTetheringState状态,执行其enter方法:

 public void enter() {            
    /*发送延时消息,超时时间5s*/
    sendMessageDelayed(obtainMessage(CMD_TETHER_NOTIFICATION_TIMED_OUT,
                    ++mTetherToken, 0), TETHER_NOTIFICATION_TIME_OUT_MSECS);
}

处于mTetheringState状态下,收到CMD_TETHER_NOTIFICATION_TIMED_OUT超时消息,则启动tether失败,一步步切换,退回到init状态。如果在超时消息之前收到CMD_TETHER_STATE_CHANGE消息,则走如下 处理:

 public boolean processMessage(Message message) {

    switch(message.what) {
        /*省略代码*/
        case CMD_TETHER_STATE_CHANGE:
                TetherStateChange stateChange = (TetherStateChange) message.obj;
                if (isWifiTethered(stateChange.active)) {
                    transitionTo(mTetheredState);
                }
                return HANDLED;
                /*省略代码*/
}

如果isWifiTethered返回成功则跳转到mTetheredState状态,并执行其enter方法。否则,超时消息到达后关闭ap。

至此整个状态机的状态历经如下切换,稳定在mThertheredState
mInitialState->mSoftApStartingState->mSoftApStartedState->mThetheringState->mThertheredState

若在mThertheredState状态下关闭AP,则按照如下流程切换
mThertheredState->mUntetheringState->mSoftApStartedState->mInitialState
这个流程中用到了deferMessage来实现相同消息的反复发送。在StateMachine章节已论述。

根据源码分析,弄清一个状态机代码流程的关键点是根据源码画出状态关系图,再根据状态逐个进行推演。如果是定位问题,可以重点使用dump功能,将状态迁徙的过程dump出来,再结合logcat进行分析。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值