了解Android中的状态机

时间:2024-04-01 17:32:04

广义地说, 任何一个程序都是一个状态机, 因为它总是要记住一些状态, 然后根据输入进行输出。 狭义上说,状态机不是指随随便便的一个程序, 而是指某一类程序,也就是状态机编程程序。

1.状态模式(State Pattern)

1.1 定义

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

1.2 适应场景

1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。
这个状态通常用一个或多个枚举常量表示。通常,有多个操作包含这一相同的条件结构。
State 模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

状态模式(State)的参与者

1.Context
定义客户感兴趣的接口。
维护一个 ConcreteState 子类的实例,这个实例定义当前状态。
2.State
定义一个接口以封装与 Context 的一个特定状态相关的行为。
3.ConcreteStatesubclasses
每一子类实现一个与 Context 的一个状态相关的行为。

状态模式(State)的 UML 类图

了解Android中的状态机

2. 有限状态机 FSM

简单讲就是将行为分为一个一个的状态,状态与状态之间的过渡通过事件的触发来形成。
比如士兵的行为有“巡逻”,“追击敌人”,“攻击敌人”,“逃跑”等行为,响应的事件就有“发
现敌人”,“追到敌人”,“敌人逃跑”,“敌人死亡”,“自己血量不足”等。那么可以写成这样
一个状态机:
1.士兵 “巡逻”,如果 “发现敌人”,那么,“追击敌人”
2.士兵 “追击敌人”, 如果 “追到敌人”, 那么,“攻击敌人”
3.士兵 “追击敌人”, 如果 “敌人死亡”, 那么,继续 “巡逻”
4.士兵 “攻击敌人”, 如果 “敌人死亡”, 那么,继续 “巡逻”
5.士兵 “攻击敌人”, 如果 “血量不足”, 那么,“逃跑”
其中,士兵就是这个 FSM 的执行者,红色的就是状态,蓝色的就是事件,
整个状态机的行为可以总结为:当前状态=>是否满足条件
1,如果是,则跳转到对应状态,否则=>是否满足条件
2,如果是,则跳转到对应状态。
由此可看出,状态机是一种“事件触发型”行为,就是只有事件的触发才会发生引起状态的变化。
但是,但如果状态过多时,状态机将变得比较复杂。为了解决这一问题,出现了一种新的状态机 HFSM。
了解Android中的状态机

3. 有限层次状态机 HFSM

HFSM 就是为了减少跳转链接而做出的努力,举个决策小狗行为的例子,我们对小狗定义了有很多行为,比如跑,吃饭,睡觉,咆哮,撒娇,摇尾巴等等,如果每个行为都是一个状态,用常规状态机的话,我们就需要在这些状态间定义跳转。

比如在“跑”的状态下,如果累了,那就跳转到“睡觉”状态;再如,在“撒娇”的状态下,如果感到有威胁,那就跳转到“咆哮”的状态等等。

我们会考量每一个状态间的关系,定义所有的跳转链接,建立这样一个状态机。如果用层次化的状态机的话,我们就先会把这些行为“分类”,把几个小状态归并到一个状态里,然后再定义高层状态和高层状态中内部小状态的跳转链接。

其实层次化状态机从某种程度上,就是限制了状态机的跳转,而且状态内的状态是不需要关心外部状态的跳转的,这样也做到了无关状态间的隔离,比如对于小狗来说,我们可以把小狗的状态先定义为疲劳,开心,愤怒,然后这些状态里再定义小状态,比如在开心的状态中,有撒桥,摇尾巴等小状态,这样我们在外部只需要关心三个状态的跳转(疲劳,开心,愤怒),在每个状态的内部只需要关心自己的小状态的跳转就可以了。这样就大大的降低了状态机的复杂度,另外,如果觉得两层的状态机还是状态太多的话,可以定义更多的状态层次以降低跳转链接数。

归类后的状态机,如下图所示
了解Android中的状态机
HFSM 被称为有限层次状态机,层状用一个专业术语就是具有行为继承,类似 OOP 中
的类继承。一般用树形网络来理解行为继承,也只有这样行为继承才能够实现。如下图所示:

了解Android中的状态机
行为继承怎么实现的呢?子状态只负责处理自己感兴趣的消息,即只处理自己的事物,
其它一切都交给父状态去处理,这样就可以认为子状态具有父状态的处理能力,也就是具有
行为继承。

4. Android 状态机框架 StateMachine

StateMachine 类作用:
这里的状态机是一个分层处理消息的状态机,并且是能够有分层排列状态。

Android 热点分享中 TetherInterfaceSMTetherMasterSM,分别用于管理网卡状态的变化
和热点状态的变化。

Android框架中还有很多StateMachine使用的实例,
BleProfileManagerState, A2dpSinkStreamingStateMachine, A2dpSinkStateMachine, SoftApManager, SupplicantStateTracker, RttStateMachine, WifiController, DcController, Dhcp6Client, DhcpClient, BondStateMachine, AdapterState, NsdStateMachine, IpManager, WifiScanningStateMachine, DhcpStateMachine , RilMessageDecoder,WakeLockStateMachine, WifiStateMachine 等 等 这 些 地 方 都 用 了 到 了StateMachine,结构都很相似。