一、Handler的定义:
主要接受子线程发送的数据, 并用此数据配合主线程更新UI.
解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。 如果此时需要一个耗时的操作,例如: 联网读取数据, 或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示 "强制关闭". 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的. 这个时候,Handler就出现了.,来解决这个复杂的问题 , 由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。
二、Handler一些特点
handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),
它有两个作用: (1): 安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行
Handler中分发消息的一些方法
[html]
1. post(Runnable)
2. postAtTime(Runnable,long)
3. postDelayed(Runnable long)
4. sendEmptyMessage(int)
5. sendMessage(Message)
6. sendMessageAtTime(Message,long)
7. sendMessageDelayed(Message,long)
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
三、Handler实例
(1) 子类需要继承Hendler类,并重写handleMessage(Message msg) 方法, 用于接受线程数据
以下为一个实例,它实现的功能为 : 通过线程修改界面Button的内容
1. public class MyHandlerActivity extends Activity {
2.
3. Button button;
4.
5. MyHandler myHandler;
6.
7.
8.
9. protected void onCreate(Bundle savedInstanceState) {
10.
11. super.onCreate(savedInstanceState);
12.
13. setContentView(R.layout.handlertest);
14.
15.
16.
17. button
18.
19. myHandler = new
20.
21. // 当创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据
22.
23. // Handler有两个作用, (1) : 定时执行Message和Runnalbe 对象
24.
25. // (2): 让一个动作,在不同的线程中执行.
26.
27.
28.
29. // 它安排消息,用以下方法
30.
31. // post(Runnable)
32.
33. // postAtTime(Runnable,long)
34.
35. // postDelayed(Runnable,long)
36.
37. // sendEmptyMessage(int)
38.
39. // sendMessage(Message);
40.
41. // sendMessageAtTime(Message,long)
42.
43. // sendMessageDelayed(Message,long)
44.
45.
46.
47. // 以上方法以 post开头的允许你处理Runnable对象
48.
49. //sendMessage()允许你处理Message对象(Message里可以包含数据,)
50.
51.
52.
53. m = new
54.
55. new Thread(m).start();
56.
57. }
58.
59.
60.
61. /**
62.
63. * 接受消息,处理消息 ,此Handler会与当前主线程一块运行
64.
65. * */
66.
67.
68.
69. class MyHandler extends Handler {
70.
71. public MyHandler() {
72.
73. }
74.
75.
76.
77. public MyHandler(Looper L) {
78.
79. super(L);
80.
81. }
82.
83.
84.
85. // 子类必须重写此方法,接受数据
86.
87. @Override
88.
89. public void handleMessage(Message msg) {
90.
91. // TODO Auto-generated method stub
92.
93. Log.d("MyHandler", "handleMessage......");
94.
95. super.handleMessage(msg);
96.
97. // 此处可以更新UI
98.
99. b = msg.getData();
100.
101. color = b.getString("color");
102.
103. MyHandlerActivity.this.button.append(color);
104.
105.
106.
107. }
108.
109. }
110.
111.
112.
113. class MyThread implements Runnable {
114.
115. public void run() {
116.
117.
118.
119. try {
120.
121. Thread.sleep(10000);
122.
123. } catch (InterruptedException e) {
124.
125. // TODO Auto-generated catch block
126.
127. e.printStackTrace();
128.
129. }
130.
131.
132.
133. Log.d("thread.......", "mThread........");
134.
135. msg = new
136.
137. b = new
138.
139. b.putString("color", "我的");
140.
141. msg.setData(b);
142.
143.
144.
145. MyHandlerActivity.this.myHandler.sendMessage(msg); // 向Handler发送消息,更新UI
146.
147.
148.
149. }
150.
151. }
152.
153.
154.
155. }
public class MyHandlerActivity extends Activity {
Button button;
MyHandler myHandler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.handlertest);
button = (Button) findViewById(R.id.button);
myHandler = new MyHandler();
// 当创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据
// Handler有两个作用, (1) : 定时执行Message和Runnalbe 对象
// (2): 让一个动作,在不同的线程中执行.
// 它安排消息,用以下方法
// post(Runnable)
// postAtTime(Runnable,long)
// postDelayed(Runnable,long)
// sendEmptyMessage(int)
// sendMessage(Message);
// sendMessageAtTime(Message,long)
// sendMessageDelayed(Message,long)
// 以上方法以 post开头的允许你处理Runnable对象
//sendMessage()允许你处理Message对象(Message里可以包含数据,)
MyThread m = new MyThread();
new Thread(m).start();
}
/**
* 接受消息,处理消息 ,此Handler会与当前主线程一块运行
* */
class MyHandler extends Handler {
public MyHandler() {
}
public MyHandler(Looper L) {
super(L);
}
// 子类必须重写此方法,接受数据
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log.d("MyHandler", "handleMessage......");
super.handleMessage(msg);
// 此处可以更新UI
Bundle b = msg.getData();
String color = b.getString("color");
MyHandlerActivity.this.button.append(color);
}
}
class MyThread implements Runnable {
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("thread.......", "mThread........");
Message msg = new Message();
Bundle b = new Bundle();// 存放数据
b.putString("color", "我的");
msg.setData(b);
MyHandlerActivity.this.myHandler.sendMessage(msg); // 向Handler发送消息,更新UI
}
}
}
例外一个案例:
1. package com.example.span.view;
2.
3. import java.util.LinkedList;
4. import android.app.AlertDialog;
5. import android.content.ComponentName;
6. import android.content.Context;
7. import android.content.DialogInterface;
8. import android.content.Intent;
9. import android.graphics.Canvas;
10. import android.graphics.Paint;
11. import android.graphics.Point;
12. import android.graphics.RectF;
13. import android.os.Handler;
14. import android.os.Message;
15. import android.util.AttributeSet;
16. import android.view.KeyEvent;
17. import android.view.View;
18. import android.widget.Toast;
19.
20. import com.example.span.view.domain.Block;
21.
22. /**
23. * 2013-6-6 上午9:24:58
24. *
25. * @author 乔晓松
26. */
27. public class GameView extends View {
28.
29. flag = true;
30. public static Block block;
31. public Handler handler;
32. dir = 2;
33. DIRTOP
34. DIRLEFT
35. DIRDOWN = 1;
36. DIRRIGHT = 2;
37. descount = 2;
38. public Canvas canvas;
39. public static Food food;
40. <Point> points = new LinkedList<Point>();
41.
42. <Point>
43. return points;
44. }
45.
46. <Point>
47. this.points = points;
48. }
49.
50. public GameView(Context context, AttributeSet attrs) {
51. super(context, attrs);
52. block = new
53. i = 0; i < 3; i++) {
54. point = new
55. block.setCx(block.getCx() - 20);
56. points.addLast(point);
57. }
58. food = new
59. handler = new
60.
61. @Override
62. public void handleMessage(Message msg) {
63. super.handleMessage(msg);
64. switch (msg.what) {
65. case DIRLEFT:
66. if (msg.what + descount != 0) {
67. descount
68. block.moveLeft();
69. } else {
70. block.moveRight();
71. }
72. break;
73. case DIRRIGHT:
74. if (msg.what + descount != 0) {
75. descount = 2;
76. block.moveRight();
77. } else {
78. block.moveLeft();
79. }
80. break;
81. case DIRTOP:
82. if (msg.what + descount != 0) {
83. descount
84. block.giveUp();
85. } else {
86. block.downLoad();
87. }
88. break;
89. case DIRDOWN:
90. if (msg.what + descount != 0) {
91. descount = 1;
92. block.downLoad();
93. } else {
94. block.giveUp();
95. }
96. break;
97. case -3:
98. Toast.makeText(getContext(), "Game Over", Toast.LENGTH_LONG)
99. .show();
100. new AlertDialog.Builder(getContext())
101. .setTitle("游戏提示")
102. .setMessage("Game Over")
103. .setPositiveButton("退出",
104. new DialogInterface.OnClickListener() {
105.
106. @Override
107. public void onClick(
108. DialogInterface dialog,
109. int which) {
110. Thread.currentThread().stop();
111. }
112. })
113. .setNegativeButton("返回菜单",
114. new DialogInterface.OnClickListener() {
115.
116. @Override
117. public void onClick(
118. DialogInterface dialog,
119. int which) {
120.
121. intent = new
122. intent.setAction("android.intent.action.MAI");
123. intent.addCategory("android.intent.category.LAUNCHER");
124. intent.setFlags(0x10200000);
125. intent.setComponent(new ComponentName(
126. "com.example.span",
127. "com.example.span.SpanActivity"));
128. getContext().startActivity(intent);
129.
130. }
131. }).show();
132. break;
133. }
134. }
135. };
136. new Thread(new Runnable() {
137.
138. @Override
139. public void run() {
140. while (flag) {
141. try {
142. Thread.sleep(500);
143. handler.sendEmptyMessage(dir);
144. } catch (InterruptedException e) {
145. e.printStackTrace();
146. }
147. }
148. handler.sendEmptyMessage(-3);
149. }
150. }).start();
151. }
152.
153. @Override
154. public boolean onKeyDown(int keyCode, KeyEvent event) {
155. System.out.println(keyCode);
156. return super.onKeyDown(keyCode, event);
157. }
158.
159. @Override
160. protected void onDraw(Canvas canvas) {
161. super.onDraw(canvas);
162. this.canvas = canvas;
163. food.chsw(canvas);
164. /*
165. descount
166. * Point(40, 40))) { System.out.println("吃掉食物了,,.."); } else { chsw(); }
167. * }
168. */
169. paint = new
170. paint.setARGB(255, 255, 140, 0);
171. for (Point p : points) {
172. rect = new
173. canvas.drawRect(rect, paint);
174. }
175. // canvas.drawArc(rect, 0, 360, true, paint);
176.
177. // canvas.drawCircle(block.getCx(), block.getCy(), 10, paint);
178. }
179.
180. }