Android 多线程之 Handler、Looper、Message 在基于 HTTP 系统中的应用

来源:互联网 发布:淘宝付款收不到验证码 编辑:程序博客网 时间:2024/05/17 01:53

1.背景

在应用TCP/IP协议进行数据传输的时候,经常用到的是IOCP的概念。我们经常试想如果HTTP的能够应用多线程的模式来进行数据的交互,将会给系统/应用带来更好的用户体验。通过线程访问WEB获取数据并将数据交给另一个线程处理是本节研究的重点。关于Handler、Looper、Message详细的原理可以参考其他博文。这里推荐《Android Looper和Handler分析》本人也是受到其启发,设计了一个简单的应用框架。

2.应用功能/任务

(1) 连接服务器获取控制指令;

(2) 执行服务器的命令;

(3) 返回执行结果;

3.设计

系统设计总图如下图所示,系统由三个线程组成:主线程、连接服务器线程、数据处理线程。

3.1基本原理

主线程用来设置定时器,开启线程;ConnectThread用来连接服务器,ConnectThread获取的数据发送给DataProcessThread,而DataProcessThread则仅仅进行数据处理,数据处理完成之后,又通过Message将结果告知ConnectThread,由ConnectThread将处理结果返回给服务器。

也就是说,在整个过程中,与服务器进行数据交互的是ConnectThread,数据处理是DataProcessThread,并且仅仅是这样。

线程ConnectThread和DataProcessThread的数据交互则通过Handler、Looper等接口来完成。ConnectThread和DataProcessThread各与一个私有的Looper和公共的Handler (分别设为handler1、handler2)绑定。

这里要注意的是,线程不存在默认的Looper,只能自行创建。并且只能在线程内部创建。如下实例:为每个线程创建一个Handler的继承类,而handleMessage则是进行数据提取的真正方法。
01.//定义子线程类中的接收消息
02. class ThreadHandler extends Handler{
03.
04. public ThreadHandler(Looper looper){
05. super(looper);
06. }
07. @Override
08. public void handleMessage(Message msg) {
09. switch (msg.what) {
10. case UPDATE_DATA://常量
11. getData();
12. break;
13. default:
14. break;
15. }
16. }
17.
18. }
19. //接收数据、处理线程
20. private Thread ReceiveThread = new Thread(){
21.
22. public void run()
23. {
24. Looper.prepare();
25. //当前线程的Looper对象
26. handler1=new ThreadHandler(Looper.myLooper());
27. Looper.loop();
28. }
29. };
30.

在两个线程进行数据传输的时候,可以采取两种方式:

①设置Request响应的全局变量Response,当ConnectThread请求到数据之后,通过handler2.sendEmptyMessage(int what)方法告知DataProcessThread,而DataProcessThread一旦接收到ConnectThread发来的空消息(因为是sendEmptyMessage发来的),则通过Response来获取数据,并进行命令执行;

② ConnectThread利用包android.os.Handler中的obtainMessage (int what, int arg1, int arg2,Object obj)和sendMessage (Message msg)对接收数据直接进行封装并发送给DataProcessThread,DataProcessThread再进行命令执行。

这两种方法就好比,我们在取信件的时候有两种方式一样,一是人家告诉我,我自己去拿二人家直接给我送来;

测试代码:(本人加入一些显示界面)
01.package home.handler;
02.
03.import java.io.BufferedReader;
04.import java.io.IOException;
05.import java.io.InputStream;
06.import java.io.InputStreamReader;
07.import java.util.Timer;
08.import java.util.TimerTask;
09.
10.import org.apache.http.HttpEntity;
11.import org.apache.http.HttpResponse;
12.import org.apache.http.client.HttpClient;
13.import org.apache.http.client.methods.HttpGet;
14.import org.apache.http.impl.client.DefaultHttpClient;
15.
16.
17.import android.app.Activity;
18.import android.os.Bundle;
19.import android.os.Handler;
20.import android.os.Looper;
21.import android.os.Message;
22.import android.view.View;
23.import android.widget.Button;
24.import android.widget.EditText;
25.
26.public class PHPHandlerActivity extends Activity {
27. protected static final int UPDATE_TEXT = 0;
28. protected static final int RETURN_RESULT = 1;
29. private Handler handler1,handler2,handler3;
30. private EditText etGet;
31. //private HttpPost request;
32. //private HttpClient client;
33. private HttpResponse response=null;
34.
35. /** Called when the activity is first created. */
36. @Override
37. public void onCreate(Bundle savedInstanceState) {
38. super.onCreate(savedInstanceState);
39. setContentView(R.layout.main);
40. etGet = (EditText)findViewById(R.id.etGet);
41. //按钮函数:开启线程
42. final Button mThreadStartButton=(Button)findViewById(R.id.button1);
43. mThreadStartButton.setOnClickListener(new Button.OnClickListener() {
44.
45. @Override
46. public void onClick(View v) {
47. // TODO Auto-generated method stub
48. ReceiveThread.start();
49. Timer timer = new Timer();
50. timer.schedule(new mTask(), 30, 1000*60*2);
51. mThreadStartButton.setEnabled(false);
52. }
53. });
54. }
55.
56. //*****************************************************************************************
57. //从此处添加自定义函数
58. //*****************************************************************************************
59. class MyHandler extends Handler{
60.
61. public MyHandler(Looper looper){
62. super(looper);
63. }
64. @Override
65. public void handleMessage(Message msg){
66. super.handleMessage(msg);
67. etGet.setText("主线程的Handler,收到了消息:"+(String)msg.obj);
68. }
69. }
70. //返回执行结果Handler
71. class ReturnHandler extends Handler{
72.
73. public ReturnHandler(Looper looper){
74. super(looper);
75. }
76. @Override
77. public void handleMessage(Message msg){
78. super.handleMessage(msg);
79. switch (msg.what) {
80. case RETURN_RESULT:
81. phpweb();
82. break;
83. default:
84. break;
85. }
86. }
87. }
88.
89. //定时器线程,连接服务器线程
90. private class mTask extends TimerTask{
91.
92. @Override
93. public void run() {
94. //连接服务器
95. HttpResponse response=phpweb();
96. if (response!=null)
97. handler1.sendEmptyMessage(UPDATE_TEXT);
98.
99. Looper.prepare();
100. //当前线程的Looper对象
101. handler3=new ReturnHandler(Looper.myLooper());
102. Looper.loop();
103. }
104. }
105. //定义子线程类中的接收消息
106. class ThreadHandler extends Handler{
107.
108. public ThreadHandler(Looper looper){
109. super(looper);
110. }
111. @Override
112. public void handleMessage(Message msg) {
113. switch (msg.what) {
114. case UPDATE_TEXT:
115. getData();
116. break;
117. default:
118. break;
119. }
120. }
121.
122. }
123. //接收数据、处理线程
124. private Thread ReceiveThread = new Thread(){
125.
126. public void run()
127. {
128. Looper.prepare();
129. //当前线程的Looper对象
130. handler1=new ThreadHandler(Looper.myLooper());
131. Looper.loop();
132. }
133. };
134.
135.
136. //数据流转换为字符串
137. private static String convertStreamToString(InputStream is) {
138. BufferedReader reader = new BufferedReader(new InputStreamReader(is));
139. StringBuilder sb = new StringBuilder();
140. String line = null;
141. try {
142. while ((line = reader.readLine()) != null) {
143. sb.append(line + "\r\n");
144. }
145. } catch (IOException e) {
146. e.printStackTrace();
147. } finally {
148. try {
149. is.close();
150. } catch (IOException e) {
151. e.printStackTrace();
152. }
153. }
154. return sb.toString();
155. }
156. //访问web函数
157. private HttpResponse phpweb(){
158.
159. try {
160. HttpClient client = new DefaultHttpClient();
161. String url = "http://www.google.com";
162. HttpGet httpGetRequest=new HttpGet(url);
163. //响应
164. response = client.execute(httpGetRequest);
165. return response;
166. }
167. catch (Exception e) {
168. // TODO: handle exception
169. e.printStackTrace();
170. }
171. return response;
172. }
173.
174. //获取数据函数
175. private void getData() {
176. try
177. {
178. HttpEntity entity = response.getEntity();
179. //返回值不为空
180. if (entity != null) {
181.
182. InputStream instream = entity.getContent();
183. String result = convertStreamToString(instream);
184. //将收到的数据返回给主界面:主线程--构造别人的Handler
185. handler2 = new MyHandler(Looper.getMainLooper());
186. Message msg2 = handler2.obtainMessage(1,1,1,result);
187. handler2.sendMessage(msg2);
188.
189. handler3.sendEmptyMessage(RETURN_RESULT);
190. }
191.
192. }
193. catch (Exception e)
194. {
195. }
196. }
197.
198.}

原创粉丝点击