天天看点

Android中的状态机 机制

 前面说过消息注册机制是messagehandler的一个应用,它的好处就是能在程序中自如地控制消息注册和消息发送两个步骤。

但是很多情况下,问题的解决是在很多个环节完成的,每个环节理解成特定的状态,在每个状态下都会有新消息的发送或者新状态的切换。那么设计就需要考虑如何将message的处理操作放到指定的状态机中,这是程序设计的关键。

总体思想:

(1)先初始化状态机,设置初始状态。

(2)内存中加载handler对象,要知道所有message的处理都的经过它,所以在复写handlemessage的时候需要将当前message分发到当前最新状态。

下面是模拟程序,刚写的,没调试,而且不全面,只写了骨架,但更直观便于阅读。明天调试看看,得出完整版本的,最好结合pdp建立过程讲解pdp建立的状态机过程。

这里列举3个类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<code>package</code>

<code>com.zte.liu.statemachine;</code>

<code>public</code>

<code>class</code> <code>hierarchicalstate {</code>

<code> </code> 

<code> </code><code>public</code>

<code>void</code> <code>enter(){</code>

<code>  </code> 

<code> </code><code>}</code>

<code>void</code> <code>exit(){</code>

<code>void</code> <code>processmessage(){</code>

<code>}</code>

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

<code>import</code>

<code>com.zte.liu.messagehandler.handlerthread;</code>

<code>com.zte.liu.messagehandler.looper;</code>

<code>com.zte.liu.messagehandler.message;</code>

<code>class</code> <code>hierarchicalstatemachine {</code>

<code> </code><code>private</code>

<code>hsmhandler mhandler;</code>

<code>handlerthread mhandlerthread;</code>

<code>defaultstate defaultstate =</code><code>new</code>

<code>defaultstate();</code>

<code>inactivestate inactivestate =</code><code>new</code>

<code>inactivestate();</code>

<code>activingstate activingstate =</code><code>new</code>

<code>activingstate();</code>

<code>activestate activestate =</code><code>new</code>

<code>activestate();</code>

<code>haltingstate haltingstate =</code><code>new</code>

<code>haltingstate();</code>

<code>quitingstate quitingstate =</code><code>new</code>

<code>quitingstate();</code>

<code>hierarchicalstatemachine(){</code>

<code>  </code><code>mhandlerthread =</code><code>new</code>

<code>handlerthread();</code>

<code>  </code><code>mhandlerthread.start();</code>

<code>  </code><code>looper looper = mhandlerthread.getlooper();</code>

<code>  </code><code>mhandler =</code><code>new</code>

<code>hsmhandler(looper);</code>

<code>class</code> <code>defaultstate</code><code>extends</code>

<code>hierarchicalstate{</code>

<code>class</code> <code>inactivestate</code><code>extends</code>

<code>class</code> <code>activingstate</code><code>extends</code>

<code>class</code> <code>activestate</code><code>extends</code>

<code>class</code> <code>haltingstate</code><code>extends</code>

<code>class</code> <code>quitingstate</code><code>extends</code>

<code>void</code> <code>addstate(hierarchicalstate state){</code>

<code>  </code><code>mhandler.addstate(state,</code><code>null</code><code>);</code>

<code>void</code> <code>addstate(hierarchicalstate state, hierarchicalstate parent){</code>

<code>  </code><code>mhandler.addstate(state, parent);</code>

<code>void</code> <code>setinitialstate(hierarchicalstate state){</code>

<code>  </code><code>mhandler.setinitialstate(state);</code>

<code>void</code> <code>start(){</code>

<code>  </code><code>mhandler.completeconstruction();</code>

<code>message obtainmessage(</code><code>int</code>

<code>what, object obj){</code>

<code>  </code><code>return</code>

<code>mhandler.obtainmessage(what, obj);</code>

<code>void</code> <code>sendmessage(message msg){</code>

<code>  </code><code>if</code><code>(msg !=</code><code>null</code><code>){</code>

<code>   </code><code>msg.sendtotarget();</code>

<code>  </code><code>}</code>

<code>void</code> <code>defermessage(message msg){</code>

<code>  </code><code>mhandler.defermessage(msg);</code>

<code>void</code> <code>transitionto(hierarchicalstate deststate){</code>

<code>  </code><code>mhandler.transitionto(deststate);</code>

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

<code>java.util.arraylist;</code>

<code>java.util.hashmap;</code>

<code>com.zte.liu.messagehandler.handler;</code>

<code>com.zte.liu.messagehandler.messagequeue;</code>

<code>class</code> <code>hsmhandler</code><code>extends</code>

<code>handler {</code>

<code>hashmap&lt;hierarchicalstate, stateinfo&gt; mstateinfo =</code><code>new</code>

<code>hashmap&lt;hierarchicalstate, stateinfo&gt;();</code>

<code>hierarchicalstate minitialstate =</code><code>null</code><code>;</code>

<code>hierarchicalstate mdeststate =</code><code>null</code><code>;</code>

<code>arraylist&lt;stateinfo&gt; minitialstatelist =</code><code>new</code>

<code>arraylist&lt;stateinfo&gt;();</code>

<code>arraylist&lt;message&gt; mdeferredmessages =</code><code>new</code>

<code>arraylist&lt;message&gt;();</code>

<code>hsmhandler(looper looper) {</code>

<code>  </code><code>super</code><code>(looper);</code>

<code>class</code> <code>stateinfo{</code>

<code>  </code><code>hierarchicalstate state;</code>

<code>  </code><code>hierarchicalstate parentstate;</code>

<code>  </code><code>boolean</code>

<code>active;</code>

<code>void</code> <code>addstate(hierarchicalstate state, hierarchicalstate parentstate){</code><code>//只在非多线程情况</code>

<code>  </code><code>if</code><code>(state ==</code><code>null</code><code>){</code>

<code>   </code><code>throw</code>

<code>new</code> <code>runtimeexception(</code><code>"state cannot be null when adding state."</code><code>);</code>

<code>/*  if(mstateinfo.containskey(state) &amp;&amp; mstateinfo.get(state).parentstate!=parentstate){</code>

<code>   </code><code>throw new runtimeexception("we cannot add a state with different parents.");</code>

<code>*/</code>

<code>  </code><code>if</code><code>(mstateinfo.containskey(state)){</code>

<code>   </code><code>return</code><code>;</code>

<code>  </code><code>stateinfo stateinfo =</code><code>new</code>

<code>stateinfo();</code>

<code>  </code><code>stateinfo.state = state;</code>

<code>  </code><code>stateinfo.parentstate = parentstate;</code>

<code>  </code><code>stateinfo.active =</code><code>false</code><code>;</code>

<code>  </code><code>mstateinfo.put(state, stateinfo);</code>

<code>  </code><code>if</code><code>(!mstateinfo.containskey(state)){</code>

<code>new</code> <code>runtimeexception(</code><code>"cannot set a initial state which is not contained in the build tree."</code><code>);</code>

<code>  </code><code>minitialstate = state;</code>

<code>void</code> <code>completeconstruction(){</code>

<code>  </code><code>if</code><code>(minitialstate ==</code><code>null</code><code>){</code>

<code>  </code><code>stateinfo initialstateinfo = mstateinfo.get(minitialstate);</code>

<code>  </code><code>while</code><code>(initialstateinfo !=</code><code>null</code><code>){</code>

<code>   </code><code>minitialstatelist.add(initialstateinfo);</code>

<code>   </code><code>if</code><code>(initialstateinfo.parentstate ==</code><code>null</code><code>){</code>

<code>    </code><code>initialstateinfo =</code><code>null</code><code>;</code>

<code>   </code><code>}</code><code>else</code><code>{</code>

<code>    </code><code>initialstateinfo = mstateinfo.get(initialstateinfo.parentstate);</code>

<code>   </code><code>}</code>

<code>  </code><code>invokeentermethods(</code><code>null</code><code>);</code>

<code>  </code><code>performtransitions();</code>

<code>void</code> <code>invokeentermethods(stateinfo commonstateinfo){</code>

<code>  </code><code>int</code>

<code>start = minitialstatelist.size() -</code><code>1</code><code>;</code>

<code>  </code><code>for</code><code>(</code><code>int</code>

<code>i=minitialstatelist.size()-</code><code>1</code><code>; i&gt;=</code><code>0</code><code>; i--){</code>

<code>   </code><code>if</code><code>(minitialstatelist.get(i) == commonstateinfo){</code>

<code>    </code><code>start = i -</code><code>1</code><code>;</code>

<code>    </code><code>break</code><code>;</code>

<code>i=start; i&gt;=</code><code>0</code><code>; i--){</code>

<code>   </code><code>stateinfo stateinfo = minitialstatelist.get(i);</code>

<code>   </code><code>stateinfo.state.enter();</code>

<code>   </code><code>stateinfo.active =</code><code>true</code><code>;</code>

<code>void</code> <code>invokeexitmethods(stateinfo commonstateinfo){</code>

<code>i=</code><code>0</code><code>; i&lt;minitialstatelist.size()-</code><code>1</code><code>; i++){</code>

<code>   </code><code>stateinfo stateinfo = (stateinfo)minitialstatelist.get(i);</code>

<code>   </code><code>if</code><code>(stateinfo != commonstateinfo){</code>

<code>    </code><code>stateinfo.state.exit();</code>

<code>    </code><code>stateinfo.active =</code><code>false</code><code>;</code>

<code>void</code> <code>performtransitions(){</code>

<code>  </code><code>if</code><code>(mdeststate ==</code><code>null</code><code>){</code>

<code>  </code><code>arraylist&lt;stateinfo&gt; templist =</code><code>new</code>

<code>  </code><code>stateinfo commonstateinfo = getcommonstateinfo(mdeststate, templist);</code>

<code>  </code><code>invokeexitmethods(commonstateinfo);</code>

<code>  </code><code>refreshinitialstatelist(commonstateinfo, templist);</code>

<code>  </code><code>invokeentermethods(commonstateinfo);</code>

<code>  </code><code>movedeferredmsgatfrontqueue();</code>

<code>  </code><code>mdeferredmessages.add(msg);</code>

<code>void</code> <code>handlemessage(message msg){</code><code>//重写!!</code>

<code>  </code><code>///////////////////////////////////////</code>

<code>  </code><code>//////////////////////////////////////</code>

<code>  </code><code>mdeststate = deststate;</code>

<code>stateinfo getcommonstateinfo(hierarchicalstate deststate, arraylist&lt;stateinfo&gt; templist){</code>

<code>  </code><code>stateinfo stateinfo = mstateinfo.get(deststate);</code>

<code>  </code><code>while</code><code>(stateinfo!=</code><code>null</code>

<code>&amp;&amp; stateinfo.active==</code><code>false</code><code>){</code>

<code>   </code><code>templist.add(stateinfo);</code>

<code>   </code><code>if</code><code>(stateinfo.parentstate ==</code><code>null</code><code>){</code>

<code>    </code><code>stateinfo =</code><code>null</code><code>;</code>

<code>    </code><code>stateinfo = mstateinfo.get(stateinfo.parentstate);</code>

<code>stateinfo;</code>

<code>void</code> <code>refreshinitialstatelist(stateinfo commonstateinfo, arraylist&lt;stateinfo&gt; templist){</code>

<code>   </code><code>if</code><code>(minitialstatelist.get(i) != commonstateinfo){</code>

<code>    </code><code>minitialstatelist.remove(i);</code>

<code>i=templist.size()-</code><code>1</code><code>; i&gt;=</code><code>0</code><code>; i--){</code>

<code>   </code><code>minitialstatelist.add(</code><code>0</code><code>, templist.get(i));</code>

<code>void</code> <code>movedeferredmsgatfrontqueue(){</code>

<code>  </code><code>messagequeue msgqueue =</code><code>this</code><code>.getlooper().getqueue();</code>

<code>i=mdeferredmessages.size()-</code><code>1</code><code>; i&gt;=</code><code>0</code><code>; i--){</code>

<code>   </code><code>msgqueue.addtofront(mdeferredmessages.get(i));</code>

继续阅读