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));

  }

 }

 

}

时间: 2025-01-20 11:20:43

Android中的状态机 机制的相关文章

消息-Android中的handler机制

问题描述 Android中的handler机制 请教大神,handler发消息可以从这个activity发送到另外一个activity吗? 解决方案 Handler 变量的定义,一般在一个 Activity 中,想要在两个 Activity 之间通过 Handler 变量,也就是说两个 Activity 都必须能看到此 Handler 变量. 这样的实现方式,就算是能实现,也不好! Activity 之间,还是通过 Receiver,如:BroadcastReceiver 来进行通讯比较好. 解

android java 回调-关于android中的回调机制 求大神帮忙看看代码

问题描述 关于android中的回调机制 求大神帮忙看看代码 boss 叫我写一个sdk 然后里面得实现回调 还给了我个demo 说回调机制和这个demo 一样 大概就是从A客户端发出一个数据 然后我这边接受 接受和执行一个事件 然后再回调给C public class DemoActivity extends Activity { private InputInterceptor input; @Override protected void onCreate(Bundle savedInst

源码-Android中事件传递机制原理

问题描述 Android中事件传递机制原理 我们知道,所有的控件直接或间接的继承子View,View的子类有ViewGroup,并且ViewGroup的子类也会有其他的子View,那么他们之间事件的传递机制是怎样的?对源码有研究的吗? 解决方案 android事件传递机制Android 事件的传递机制Android之事件传递机制 解决方案二: http://blog.csdn.net/pi9nc/article/details/9281829http://www.csdn123.com/html

Android中Handler消息传递机制_Android

Handler 是用来干什么的? 1)执行计划任务,可以在预定的时间执行某些任务,可以模拟定时器 2)线程间通信.在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息.当你创建子线程时,你可以在你的子线程中拿到父线程中创建的Handler 对象,就可以通过该对象向父线程的消息队列发送消息了.由于Android要求在UI线程中更新界面,因此,可以通过该方法在其它线程中更新界面. 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发

Android中Handler消息传递机制

Handler 是用来干什么的? 1)执行计划任务,可以在预定的时间执行某些任务,可以模拟定时器 2)线程间通信.在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息.当你创建子线程时,你可以在你的子线程中拿到父线程中创建的Handler 对象,就可以通过该对象向父线程的消息队列发送消息了.由于Android要求在UI线程中更新界面,因此,可以通过该方法在其它线程中更新界面. 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发

Android中的IPC机制

IPC是 Inter-Proscess Communication的缩写,含义为进程间的通讯或者跨进程通讯,是指两个进程之间进行数据交换的过程.按操作系统的中的描述,线程是CPU调度最小的单元,同时线程是一种有限的系统资源,而进程是指一个执行单元,在PC和移动设备上指一个程序或者一个应用.一个进程可以包含多个线程,因此进程和线程是包含于被包含的关系. IPC的使用场景就必须提到多进程,只有面对多进程这种场景下,才需要考虑进程间通讯.多进程的情况分为两种:第一种是一个应用因为某些原因自身需要采用多

Android中对Handle机制的理解

一.重要参考资料 [参考资料]    目前来看,下面的几个网址中的内容质量比较不错,基本不需要再读别的网址了. 1.android消息机制一    http://xtfncel.javaeye.com/blog/663517  Android消息机制(一) 一.    角色描述 1.Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列). 2.Handler: 你可以构造Handler对象来与Looper沟通,以便push新消息到Mess

Android中事件传递机制的总结

事件传递虽然算不上某个单独的知识点,但是在实际项目开发中肯定会碰到,如果不明白其中的原理,那在设计各种滑动效果时就会感到很困惑. 关于事件的传递,我们可能会有以下疑问: 事件是如何传递的 事件是如何处理的 自定义view的时候,事件也冲突了怎么解决 带着这三个疑问,我们来总结一下事件传递机制是怎么回事.   一.事件分发的原理: 1.事件是如何传递的: (1)首先由Activity分发,分发给根View,也就是DecorView(DecorView为整个Window界面的最顶层View) (2)

详细介绍Android中回调函数机制_Android

提示:在阅读本文章之前,请确保您对Touch事件的分发机制有一定的了解 在Android的学习过程中经常会听到或者见到"回调"这个词,那么什么是回调呢?所谓的回调函数就是:在A类中定义了一个方法,这个方法中用到了一个接口和该接口中的抽象方法,但是抽象方法没有具体的实现,需要B类去实现,B类实现该方法后,它本身不会去调用该方法,而是传递给A类,供A类去调用,这种机制就称为回调. 下面我们拿具体的Button的点击事件进行模拟分析: 首先,在View类中我们能找到setOnClickLis