1.背景
在应用TCP/IP协议进行数据传输的时候,经常用到的是IOCP的概念。我们经常试想如果HTTP的能够应用多线程的模式来进行数据的交互,将会给系统/应用带来更好的用户体验。通过线程访问WEB获取数据并将数据交给另一个线程处理是本节研究的重点。关于Handler、Looper、Message详细的原理可以参考其他文章。这里推荐《
Android Looper和Handler分析》(见 http://www.linuxidc.com/Linux/2012-07/64095.htm)本人也是受到其启发,设计了一个简单的应用框架。
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则是进行数据提取的真正方法。
- //定义子线程类中的接收消息
- class ThreadHandler extends Handler{
-
- public ThreadHandler(Looper looper){
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case UPDATE_DATA://常量
- getData();
- break;
- default:
- break;
- }
- }
-
- }
- //接收数据、处理线程
- private Thread ReceiveThread = new Thread(){
-
- public void run()
- {
- Looper.prepare();
- //当前线程的Looper对象
- handler1=new ThreadHandler(Looper.myLooper());
- Looper.loop();
- }
- };
-
在两个线程进行数据传输的时候,可以采取两种方式:①设置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再进行命令执??。这两种方法就好比,我们在取信件的时候有两种方式一样,一是人家告诉我,我自己去拿二人家直接给我送来;测试代码:(本人加入一些显示界面)
- package home.handler;
-
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.util.Timer;
- import java.util.TimerTask;
-
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
-
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Looper;
- import android.os.Message;
- import android.view.View;
- import android.widget.Button;
- import android.widget.EditText;
-
- public class PHPHandlerActivity extends Activity {
- protected static final int UPDATE_TEXT = 0;
- protected static final int RETURN_RESULT = 1;
- private Handler handler1,handler2,handler3;
- private EditText etGet;
- //private HttpPost request;
- //private HttpClient client;
- private HttpResponse response=null;
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- etGet = (EditText)findViewById(R.id.etGet);
- //按钮函数:开启线程
- final Button mThreadStartButton=(Button)findViewById(R.id.button1);
- mThreadStartButton.setOnClickListener(new Button.OnClickListener() {
-
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- ReceiveThread.start();
- Timer timer = new Timer();
- timer.schedule(new mTask(), 30, 1000*60*2);
- mThreadStartButton.setEnabled(false);
- }
- });
- }
-
- //*****************************************************************************************
- //从此处添加自定义函数
- //*****************************************************************************************
- class MyHandler extends Handler{
-
- public MyHandler(Looper looper){
- super(looper);
- }
- @Override
- public void handleMessage(Message msg){
- super.handleMessage(msg);
- etGet.setText("主线程的Handler,收到了消息:"+(String)msg.obj);
- }
- }
- //返回执行结果Handler
- class ReturnHandler extends Handler{
-
- public ReturnHandler(Looper looper){
- super(looper);
- }
- @Override
- public void handleMessage(Message msg){
- super.handleMessage(msg);
- switch (msg.what) {
- case RETURN_RESULT:
- phpweb();
- break;
- default:
- break;
- }
- }
- }
-
- //定时器线程,连接服务器线程
- private class mTask extends TimerTask{
-
- @Override
- public void run() {
- //连接服务器
- HttpResponse response=phpweb();
- if (response!=null)
- handler1.sendEmptyMessage(UPDATE_TEXT);
-
- Looper.prepare();
- //当前线程的Looper对象
- handler3=new ReturnHandler(Looper.myLooper());
- Looper.loop();
- }
- }
- //定义子线程类中的接收消息
- class ThreadHandler extends Handler{
-
- public ThreadHandler(Looper looper){
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case UPDATE_TEXT:
- getData();
- break;
- default:
- break;
- }
- }
-
- }
- //接收数据、处理线程
- private Thread ReceiveThread = new Thread(){
-
- public void run()
- {
- Looper.prepare();
- //当前线程的Looper对象
- handler1=new ThreadHandler(Looper.myLooper());
- Looper.loop();
- }
- };
-
-
- //数据流转换为字符串
- private static String convertStreamToString(InputStream is) {
- BufferedReader reader = new BufferedReader(new InputStreamReader(is));
- StringBuilder sb = new StringBuilder();
- String line = null;
- try {
- while ((line = reader.readLine()) != null) {
- sb.append(line + "
");
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return sb.toString();
- }
- //访问web函数
- private HttpResponse phpweb(){
-
- try {
- HttpClient client = new DefaultHttpClient();
- String url = "http://www.linuxidc.com";
- HttpGet httpGetRequest=new HttpGet(url);
- //响应
- response = client.execute(httpGetRequest);
- return response;
- }
- catch (Exception e) {
- // TODO: handle exception
- e.printStackTrace();
- }
- return response;
- }
-
- //获取数据函数
- private void getData() {
- try
- {
- HttpEntity entity = response.getEntity();
- //返回值不为空
- if (entity != null) {
-
- InputStream instream = entity.getContent();
- String result = convertStreamToString(instream);
- //将收到的数据返回给主界面:主线程--构造别人的Handler
- handler2 = new MyHandler(Looper.getMainLooper());
- Message msg2 = handler2.obtainMessage(1,1,1,result);
- handler2.sendMessage(msg2);
-
- handler3.sendEmptyMessage(RETURN_RESULT);
- }
-
- }
- catch (Exception e)
- {
- }
- }
-
- }