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
|
package
com.zte.liu.statemachine;
public
class
HierarchicalState {
public
void
enter(){
}
public
void
exit(){
}
public
void
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
|
package
com.zte.liu.statemachine;
import
com.zte.liu.messagehandler.HandlerThread;
import
com.zte.liu.messagehandler.Looper;
import
com.zte.liu.messagehandler.Message;
public
class
HierarchicalStateMachine {
private
HsmHandler mHandler;
private
HandlerThread mHandlerThread;
private
DefaultState defaultState = new
DefaultState();
private
InactiveState inActiveState = new
InactiveState();
private
ActivingState activingState = new
ActivingState();
private
ActiveState activeState = new
ActiveState();
private
HaltingState haltingState = new
HaltingState();
private
QuitingState quitingState = new
QuitingState();
public
HierarchicalStateMachine(){
mHandlerThread
= new
HandlerThread();
mHandlerThread.start();
Looper
looper = mHandlerThread.getLooper();
mHandler
= new
HsmHandler(looper);
}
private
class
DefaultState extends
HierarchicalState{
}
private
class
InactiveState extends
HierarchicalState{
}
private
class
ActivingState extends
HierarchicalState{
}
private
class
ActiveState extends
HierarchicalState{
}
private
class
HaltingState extends
HierarchicalState{
}
private
class
QuitingState extends
HierarchicalState{
}
public
void
addState(HierarchicalState state){
mHandler.addState(state,
null );
}
public
void
addState(HierarchicalState state, HierarchicalState parent){
mHandler.addState(state,
parent);
}
public
void
setInitialState(HierarchicalState state){
mHandler.setInitialState(state);
}
public
void
start(){
mHandler.completeConstruction();
}
public
Message obtainMessage( int
what, Object obj){
return
mHandler.obtainMessage(what, obj);
}
public
void
sendMessage(Message msg){
if (msg
!= null ){
msg.sendToTarget();
}
}
public
void
deferMessage(Message msg){
mHandler.deferMessage(msg);
}
public
void
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
|
package
com.zte.liu.statemachine;
import
java.util.ArrayList;
import
java.util.HashMap;
import
com.zte.liu.messagehandler.Handler;
import
com.zte.liu.messagehandler.Looper;
import
com.zte.liu.messagehandler.Message;
import
com.zte.liu.messagehandler.MessageQueue;
public
class
HsmHandler extends
Handler {
private
HashMap<HierarchicalState, StateInfo> mStateInfo = new
HashMap<HierarchicalState, StateInfo>();
private
HierarchicalState mInitialState = null ;
private
HierarchicalState mDestState = null ;
private
ArrayList<StateInfo> mInitialStateList = new
ArrayList<StateInfo>();
private
ArrayList<Message> mDeferredMessages = new
ArrayList<Message>();
public
HsmHandler(Looper looper) {
super (looper);
}
private
class
StateInfo{
HierarchicalState
state;
HierarchicalState
parentState;
boolean
active;
}
public
void
addState(HierarchicalState state, HierarchicalState parentState){ //只在非多线程情况
if (state
== null ){
throw
new
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 = new
StateInfo();
stateInfo.state
= state;
stateInfo.parentState
= parentState;
stateInfo.active
= false ;
mStateInfo.put(state,
stateInfo);
}
public
void
setInitialState(HierarchicalState state){
if (!mStateInfo.containsKey(state)){
throw
new
RuntimeException( "cannot
set a initial state which is not contained in the build tree." );
}
mInitialState
= state;
}
public
void
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();
}
public
void
invokeEnterMethods(StateInfo commonStateInfo){
int
start = mInitialStateList.size() - 1 ;
for ( int
i=mInitialStateList.size()- 1 ;
i>= 0 ;
i--){
if (mInitialStateList.get(i)
== commonStateInfo){
start
= i - 1 ;
break ;
}
}
for ( int
i=start; i>= 0 ;
i--){
StateInfo
stateInfo = mInitialStateList.get(i);
stateInfo.state.enter();
stateInfo.active
= true ;
}
}
public
void
invokeExitMethods(StateInfo commonStateInfo){
for ( int
i= 0 ;
i<mInitialStateList.size()- 1 ;
i++){
StateInfo
stateInfo = (StateInfo)mInitialStateList.get(i);
if (stateInfo
!= commonStateInfo){
stateInfo.state.exit();
stateInfo.active
= false ;
} else {
break ;
}
}
}
public
void
performTransitions(){
if (mDestState
== null ){
return ;
}
ArrayList<StateInfo>
tempList = new
ArrayList<StateInfo>();
StateInfo
commonStateInfo = getCommonStateInfo(mDestState, tempList);
invokeExitMethods(commonStateInfo);
refreshInitialStateList(commonStateInfo,
tempList);
invokeEnterMethods(commonStateInfo);
moveDeferredMsgAtFrontQueue();
}
public
void
deferMessage(Message msg){
mDeferredMessages.add(msg);
}
public
void
handleMessage(Message msg){ //重写!!
///////////////////////////////////////
//////////////////////////////////////
}
public
void
transitionTo(HierarchicalState destState){
mDestState
= destState;
}
private
StateInfo 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);
}
}
return
stateInfo;
}
private
void
refreshInitialStateList(StateInfo commonStateInfo, ArrayList<StateInfo> tempList){
for ( int
i= 0 ;
i<mInitialStateList.size()- 1 ;
i++){
if (mInitialStateList.get(i)
!= commonStateInfo){
mInitialStateList.remove(i);
}
}
for ( int
i=tempList.size()- 1 ;
i>= 0 ;
i--){
mInitialStateList.add( 0 ,
tempList.get(i));
}
}
private
void
moveDeferredMsgAtFrontQueue(){
MessageQueue
msgQueue = this .getLooper().getQueue();
for ( int
i=mDeferredMessages.size()- 1 ;
i>= 0 ;
i--){
msgQueue.addToFront(mDeferredMessages.get(i));
}
}
}
|
最后更新:2017-04-02 06:52:03