Android StateMachine

狀態(tài)機(jī)

狀態(tài)機(jī)定義

狀態(tài)機(jī)待德,F(xiàn)inite state machine,簡(jiǎn)稱FSM枫夺。指一個(gè)對(duì)象在有限個(gè)狀態(tài)內(nèi)轉(zhuǎn)移并處理外部事件的數(shù)字模型。

狀態(tài)機(jī)定義

如圖所示绘闷,一個(gè)對(duì)象有n個(gè)狀態(tài)橡庞。假設(shè)初始狀態(tài)為State1较坛,當(dāng)外部事件到來時(shí),處在狀態(tài)State1的對(duì)象處理這個(gè)狀態(tài)并轉(zhuǎn)移到狀態(tài)State2扒最,而這個(gè)對(duì)象在狀態(tài)State2時(shí)接收到外部事件時(shí)又會(huì)處理這個(gè)事件并轉(zhuǎn)移到另外一個(gè)狀態(tài)丑勤。

比如,我們通話的聲道會(huì)有揚(yáng)聲器吧趣、耳機(jī)法竞、聽筒、藍(lán)牙4個(gè)狀態(tài)强挫。假設(shè)我們這通通話的聲道初始狀態(tài)為聽筒岔霸,當(dāng)用戶在通話界面把聲道切為揚(yáng)聲器時(shí),聽筒這個(gè)狀態(tài)會(huì)打開揚(yáng)聲器并轉(zhuǎn)移到揚(yáng)聲器狀態(tài)俯渤。打開揚(yáng)聲器這個(gè)動(dòng)作呆细,我們可以在聽筒狀態(tài)轉(zhuǎn)移到揚(yáng)聲器之前處理,也可以在進(jìn)入揚(yáng)聲器狀態(tài)時(shí)處理八匠。因此絮爷,我們可以有一個(gè)擴(kuò)展的狀態(tài)機(jī)定義:

帶enter exit action的狀態(tài)機(jī)

這個(gè)狀態(tài)機(jī)比上面的狀態(tài)機(jī)每個(gè)State多了enter和exit兩個(gè)action,表示在進(jìn)入或者退出某個(gè)狀態(tài)時(shí)會(huì)做的動(dòng)作梨树,比如上面那個(gè)例子中揚(yáng)聲器State的enter action可以打開揚(yáng)聲器而其exit action可以關(guān)閉揚(yáng)聲器坑夯。如圖所示:

AudioRoute狀態(tài)機(jī)

分層狀態(tài)機(jī)

分層狀態(tài)機(jī),Hierarchical Finite State Machine抡四,簡(jiǎn)稱HFSM柜蜈。即對(duì)象的N個(gè)有限狀態(tài)中的某個(gè)狀態(tài)可以有N個(gè)子狀態(tài)。這里不細(xì)講床嫌。

狀態(tài)機(jī)模式

狀態(tài)機(jī)模式定義

實(shí)現(xiàn)狀態(tài)機(jī)的一種方法就是狀態(tài)機(jī)模式(State Pattern)跨释,其定義如下:

狀態(tài)機(jī)模式

定義一個(gè)狀態(tài)接口State,在外部事件message到來時(shí)厌处,State處理該事件并在其實(shí)現(xiàn)類之前轉(zhuǎn)移鳖谈。其時(shí)序圖如下:

狀態(tài)機(jī)模式時(shí)序圖

下面我們將通過Android狀態(tài)機(jī)StateMachine來詳細(xì)講解這個(gè)模式的設(shè)計(jì)和使用。

Android狀態(tài)機(jī)

設(shè)計(jì)及實(shí)現(xiàn)

Android原生通過狀態(tài)機(jī)模式實(shí)現(xiàn)了一個(gè)分層狀態(tài)機(jī)名為StateMachine阔涉。其結(jié)構(gòu)如下:

Android StateMachine結(jié)構(gòu)

一個(gè)狀態(tài)機(jī)對(duì)象缆娃,由一棵狀態(tài)樹,及實(shí)現(xiàn)狀態(tài)轉(zhuǎn)移并接收外部事件給當(dāng)前狀態(tài)處理的SmHandler構(gòu)成瑰排。其具體流程的時(shí)序圖如下:

Android StateMachine時(shí)序圖

1. 構(gòu)建一棵狀態(tài)樹(可多層)贯要。

2. 設(shè)置初始狀態(tài)。

3. 啟動(dòng)狀態(tài)機(jī)椭住。即崇渗,進(jìn)入初始狀態(tài),并完成初始狀態(tài)的enter action。

4. 狀態(tài)機(jī)收到一個(gè)外部事件宅广,并交由SmHandler處理葫掉,SmHandler通知當(dāng)前狀態(tài)處理事件,如果當(dāng)前狀態(tài)處理完這個(gè)事件后需要狀態(tài)轉(zhuǎn)移跟狱,則由SmHandler完成狀態(tài)轉(zhuǎn)移俭厚。

5. 退出當(dāng)前狀態(tài)時(shí),SmHandler通知當(dāng)前狀態(tài)處理exit action驶臊。進(jìn)入新狀態(tài)之前挪挤,SmHandler通知新狀態(tài)先處理其enter action。

6. SmHandler在通知當(dāng)前狀態(tài)處理事件前和狀態(tài)完成事件處理之后关翎,會(huì)回調(diào)StateMachine處理準(zhǔn)備和結(jié)束動(dòng)作扛门。

使用方法

狀態(tài)機(jī)的使用很簡(jiǎn)單,如圖

Android StateMachine使用

只需要建立一個(gè)StateMachine的實(shí)現(xiàn)類笤休,在這個(gè)實(shí)現(xiàn)類中創(chuàng)建State的各個(gè)實(shí)現(xiàn)尖飞,通過StateMachine#addState()構(gòu)建狀態(tài)樹,開啟狀態(tài)機(jī)店雅。

其具體流程可參考下圖:

Android StateMachine流程

應(yīng)用

具體應(yīng)用請(qǐng)參考?Android通話應(yīng)用設(shè)計(jì)?中關(guān)于CalAudioRouteStateMachine和CallAudioModeStateMachine的介紹政基。


原創(chuàng)內(nèi)容歡迎轉(zhuǎn)載,但請(qǐng)注明出處闹啦,謝謝沮明!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市窍奋,隨后出現(xiàn)的幾起案子荐健,更是在濱河造成了極大的恐慌,老刑警劉巖琳袄,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件江场,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡窖逗,警方通過查閱死者的電腦和手機(jī)址否,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碎紊,“玉大人佑附,你說我怎么就攤上這事≌炭迹” “怎么了音同?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)秃嗜。 經(jīng)常有香客問我权均,道長(zhǎng)顿膨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任叽赊,我火速辦了婚禮虽惭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蛇尚。我一直安慰自己,他們只是感情好顾画,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布取劫。 她就那樣靜靜地躺著,像睡著了一般研侣。 火紅的嫁衣襯著肌膚如雪谱邪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天庶诡,我揣著相機(jī)與錄音惦银,去河邊找鬼。 笑死末誓,一個(gè)胖子當(dāng)著我的面吹牛扯俱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播喇澡,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼迅栅,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了晴玖?” 一聲冷哼從身側(cè)響起读存,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呕屎,沒想到半個(gè)月后让簿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秀睛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年尔当,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片琅催。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡居凶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出藤抡,到底是詐尸還是另有隱情侠碧,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布缠黍,位于F島的核電站弄兜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜替饿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一语泽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧视卢,春花似錦芹枷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绳锅,卻和暖如春西饵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鳞芙。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工眷柔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人原朝。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓驯嘱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親竿拆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宙拉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355