Android中的状态机 机制

来源:互联网 发布:windows磁盘分区 编辑:程序博客网 时间:2024/06/01 16:22
 前面说过消息注册机制是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
packagecom.zte.liu.statemachine;
 
publicclass HierarchicalState {
  
 publicvoid enter(){
   
 }
 publicvoid exit(){
   
 }
 publicvoid processMessage(){
   
 }
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
packagecom.zte.liu.statemachine;
 
importcom.zte.liu.messagehandler.HandlerThread;
importcom.zte.liu.messagehandler.Looper;
importcom.zte.liu.messagehandler.Message;
 
publicclass HierarchicalStateMachine {
  
 privateHsmHandler mHandler;
 privateHandlerThread mHandlerThread;
  
 privateDefaultState defaultState = newDefaultState();
 privateInactiveState inActiveState = newInactiveState();
 privateActivingState activingState = newActivingState();
 privateActiveState activeState = newActiveState();
 privateHaltingState haltingState = newHaltingState();
 privateQuitingState quitingState = newQuitingState();
  
 publicHierarchicalStateMachine(){
  mHandlerThread = newHandlerThread();
  mHandlerThread.start();
  Looper looper = mHandlerThread.getLooper();
  mHandler = newHsmHandler(looper);
 }
  
 privateclass DefaultState extendsHierarchicalState{
   
 }
  
 privateclass InactiveState extendsHierarchicalState{
   
 }
  
 privateclass ActivingState extendsHierarchicalState{
   
 }
  
 privateclass ActiveState extendsHierarchicalState{
   
 }
 
 privateclass HaltingState extendsHierarchicalState{
   
 }
  
 privateclass QuitingState extendsHierarchicalState{
   
 }
  
 publicvoid addState(HierarchicalState state){
  mHandler.addState(state,null);
 }
  
 publicvoid addState(HierarchicalState state, HierarchicalState parent){
  mHandler.addState(state, parent);
 }
  
 publicvoid setInitialState(HierarchicalState state){
  mHandler.setInitialState(state);
 }
  
 publicvoid start(){
  mHandler.completeConstruction();
 }
  
 publicMessage obtainMessage(intwhat, Object obj){
  returnmHandler.obtainMessage(what, obj);
 }
  
 publicvoid sendMessage(Message msg){
  if(msg != null){
   msg.sendToTarget();
  }
 }
  
 publicvoid deferMessage(Message msg){
  mHandler.deferMessage(msg);
 }
  
 publicvoid transitionTo(HierarchicalState destState){
  mHandler.transitionTo(destState);
 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
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
packagecom.zte.liu.statemachine;
 
importjava.util.ArrayList;
importjava.util.HashMap;
 
importcom.zte.liu.messagehandler.Handler;
importcom.zte.liu.messagehandler.Looper;
importcom.zte.liu.messagehandler.Message;
importcom.zte.liu.messagehandler.MessageQueue;
 
publicclass HsmHandler extendsHandler {
  
 privateHashMap<HierarchicalState, StateInfo> mStateInfo = newHashMap<HierarchicalState, StateInfo>();
 privateHierarchicalState mInitialState = null;
 privateHierarchicalState mDestState = null;
 privateArrayList<StateInfo> mInitialStateList = newArrayList<StateInfo>();
 privateArrayList<Message> mDeferredMessages = newArrayList<Message>();
  
 publicHsmHandler(Looper looper) {
  super(looper);
 }
  
 privateclass StateInfo{
  HierarchicalState state;
  HierarchicalState parentState;
  booleanactive;
 }
  
 publicvoid addState(HierarchicalState state, HierarchicalState parentState){//只在非多线程情况
  if(state == null){
   thrownew RuntimeException("state cannot be null when adding state.");
  }
/*  if(mStateInfo.containsKey(state) && mStateInfo.get(state).parentState!=parentState){
   throw new RuntimeException("we cannot add a state with different parents.");
  }
*/
  if(mStateInfo.containsKey(state)){
   return;
  }
  StateInfo stateInfo = newStateInfo();
  stateInfo.state = state;
  stateInfo.parentState = parentState;
  stateInfo.active = false;
  mStateInfo.put(state, stateInfo);
 }
  
 publicvoid setInitialState(HierarchicalState state){
  if(!mStateInfo.containsKey(state)){
   thrownew RuntimeException("cannot set a initial state which is not contained in the build tree.");
  }
  mInitialState = state;
 }
  
 publicvoid completeConstruction(){
  if(mInitialState == null){
   return;
  }
  StateInfo initialStateInfo = mStateInfo.get(mInitialState);
  while(initialStateInfo != null){
   mInitialStateList.add(initialStateInfo);
   if(initialStateInfo.parentState == null){
    initialStateInfo = null;
   }else{
    initialStateInfo = mStateInfo.get(initialStateInfo.parentState);
   }
  }
   
  invokeEnterMethods(null);
   
  performTransitions();
 }
  
 publicvoid invokeEnterMethods(StateInfo commonStateInfo){
  intstart = mInitialStateList.size() - 1;
  for(inti=mInitialStateList.size()-1; i>=0; i--){
   if(mInitialStateList.get(i) == commonStateInfo){
    start = i - 1;
    break;
   }
  }
  for(inti=start; i>=0; i--){
   StateInfo stateInfo = mInitialStateList.get(i);
   stateInfo.state.enter();
   stateInfo.active = true;
  }
 }
  
 publicvoid invokeExitMethods(StateInfo commonStateInfo){
  for(inti=0; i<mInitialStateList.size()-1; i++){
   StateInfo stateInfo = (StateInfo)mInitialStateList.get(i);
   if(stateInfo != commonStateInfo){
    stateInfo.state.exit();
    stateInfo.active = false;
   }else{
    break;
   }
  }
 }
  
 publicvoid performTransitions(){
  if(mDestState == null){
   return;
  }
  ArrayList<StateInfo> tempList = newArrayList<StateInfo>();
  StateInfo commonStateInfo = getCommonStateInfo(mDestState, tempList);
  invokeExitMethods(commonStateInfo);
  refreshInitialStateList(commonStateInfo, tempList);
  invokeEnterMethods(commonStateInfo);
  moveDeferredMsgAtFrontQueue();
 }
  
 publicvoid deferMessage(Message msg){
  mDeferredMessages.add(msg);
 }
  
 publicvoid handleMessage(Message msg){//重写!!
  ///////////////////////////////////////
   
  //////////////////////////////////////
 }
  
 publicvoid transitionTo(HierarchicalState destState){
  mDestState = destState;
 }
  
 privateStateInfo getCommonStateInfo(HierarchicalState destState, ArrayList<StateInfo> tempList){
  StateInfo stateInfo = mStateInfo.get(destState);
  while(stateInfo!=null&& stateInfo.active==false){
   tempList.add(stateInfo);
   if(stateInfo.parentState == null){
    stateInfo = null;
   }else{
    stateInfo = mStateInfo.get(stateInfo.parentState);
   }
  }
  returnstateInfo;
 }
  
 privatevoid refreshInitialStateList(StateInfo commonStateInfo, ArrayList<StateInfo> tempList){
  for(inti=0; i<mInitialStateList.size()-1; i++){
   if(mInitialStateList.get(i) != commonStateInfo){
    mInitialStateList.remove(i);
   }
  }
  for(inti=tempList.size()-1; i>=0; i--){
   mInitialStateList.add(0, tempList.get(i));
  }
 }
  
 privatevoid moveDeferredMsgAtFrontQueue(){
  MessageQueue msgQueue = this.getLooper().getQueue();
  for(inti=mDeferredMessages.size()-1; i>=0; i--){
   msgQueue.addToFront(mDeferredMessages.get(i));
  }
 }
 
}