Android--Handler+Looper+MessageQueue+Thread线程之间的通信
来源:互联网 发布:公司域名注册 编辑:程序博客网 时间:2024/05/29 17:12
几个关键概念:(参考网络相关博客)
1、MessageQueue:
- 是一种数据结构,见名知义,就是一个消息队列,存放消息的地方;
- 每一个线程最多只可以拥有一个MessageQueue数据结构;
- 一个线程存在MessageQueue才能接收消息;
- 通常使用一个Looper象对该线程的MessageQueue进行管理;
- 主线程创建时,会创建一个默认的Looper对象和MessageQueue;
- 其他非主线程,不会自动创建Looper,要需要的时候,通过调用prepare()函数来实现创建和某个线程关联的Looper,创建了关联的Looper就会自动创建一个MessageQueue。
2、Message:
- 消息对象,Message Queue中的存放的对象; 一个Message Queue中包含多个Message;
- Message实例对象的取得,通常使用Message类里的静态方法obtain(),该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,而是先从MessagePool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。如果MessagePool中没有可用的Message实例,则才用给定的参数创建一个Message对象。调用removeMessages()时,将Message从MessageQueue中删除,同时放入到Message Pool中;
- 除了上面这种方式,也可以通过Handler对象的obtainMessage()获取一个Message实例。
3、Looper:
- 是MessageQueue的管理者;
- 每一个MessageQueue都不能脱离Looper而存在,Looper对象的创建是通过prepare函数来实现的;
- 同时每一个Looper对象和一个线程关联;
- 通过调用Looper.myLooper()可以获得当前线程的Looper对象;
- 创建一个Looper对象时,会同时创建一个MessageQueue对象;
- 除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能接受Message。如需要接受,自己定义一个Looper对象(通过Looper.prepare()函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了;
- Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理;
- 处理完成后,调用Message.recycle()将其放入Message Pool中。
4、Handler:
消息的处理者,handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现;
将消息传递给Looper,这是通过handler对象的sendMessage()来实现的;
继而由Looper将Message放入MessageQueue中;
当Looper对象看到MessageQueue中含有Message,就将其广播出去;该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法对其进行处理。
具体代码如下所示:
主线程(UI线程)
package com.longshun.HandlerLooperHomework;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.EditText;import android.widget.TextView;import android.widget.Toast;//1.主线程,向子线程发消息;// 2.子线程接收主线程的消息,// 子线程根据主线程发过来的消息访问网络,得到数据后发送给主线程;public class MainActivity extends Activity { //主线程有默认的Looper private EditText txtUiMsg; private TextView txtRes; private Handler cHandler; private ChildThread childThread; //主线程要得到子线程的消息,先创建一个Handler Handler fHandler = new Handler() { @Override public void handleMessage(Message msg) { int what = msg.what; Object obj = msg.obj; switch (what) { case 0: txtRes.setText(obj.toString());//设置ui内容 break; } } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); txtUiMsg = (EditText) findViewById(R.id.txt_ui_msg); txtRes = (TextView) findViewById(R.id.txt_return_msg); //得到子线程任务对象,把主线程传给子线程,因为如果子线程要发消息给主线程,必须要有主线程的handler childThread = new ChildThread(fHandler); //启动子线程,子线程处于等待主线程发消息的状态 Thread thread = new Thread(childThread); thread.start(); } //点击按钮 主线程获取输入框内容 发送给子线程 public void btnSendMsg(View view) { //获取输入框内容,去除前后空格 String UiMsg = String.valueOf(txtUiMsg.getText()).trim().replace(" ", ""); if (UiMsg != null && UiMsg.length() > 0) { //得到与子线程关联的Handler,向子线程发消息 cHandler = childThread.getcHandler(); Message message = cHandler.obtainMessage(1); message.obj = UiMsg; cHandler.sendMessage(message);//发送消息给子线程 Toast.makeText(this, "send success and wait response!", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "请输入你想对小黄鸡说的话!", Toast.LENGTH_SHORT).show(); } } @Override protected void onDestroy() { if (cHandler != null) { cHandler.getLooper().quit();//得到和子线程相关的Looper,并且终止MessageQueue运行; } super.onDestroy(); }}
子线程:
package com.longshun.HandlerLooperHomework;import android.os.Handler;import android.os.Looper;import android.os.Message;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 org.json.JSONException;import org.json.JSONObject;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;/** * Created by LongShun on 2015/9/7. * Author:LongShun * Email:1261972397@qq.com *///子线程任务对象public class ChildThread implements Runnable { private Handler cHandler; private Handler fHandler; //子线程要向主线程发消息,所以要得到与主线程绑定的fHandler, // 通过这个fHandler才能给主线程发消息。 public ChildThread(Handler fHandler) { this.fHandler = fHandler; } @Override public void run() { Looper.prepare();//!!!!!!!!创建一个和当前线程绑定的Looper,自动创建一个MessageQueue对象, // !!!!!!!!!!!有了MessageQueue对象就能接收Message对象--消息 //和子线程绑定的cHandler,用来处理主线程发过来的消息。 //等待主线程发消息,有消息就处理,没消息就处于等待状态 cHandler = new Handler(){ @Override public void handleMessage(Message msg) { int what = msg.what; switch (what){ case 1: //1得到主线程发过来的消息 String uiMsg = msg.obj.toString(); //2根据消息,联网访问,得到结果 String res = getResponse(uiMsg); //3.通过主线程fHandler ,把响应结果发送给主线程。 Message message = fHandler.obtainMessage(0); message.obj = res; fHandler.sendMessage(message); break; } } }; Looper.loop();//用于不断循环地从MessageQueue中取消息 } //得到与子线程绑定的cHandler public Handler getcHandler(){ return cHandler; } //解析json字符串 public String parserResult(String jsonString){ String result=null; if (jsonString!=null){ try { JSONObject jsonObject = new JSONObject(jsonString); result = jsonObject.getString("res"); } catch (JSONException e) { e.printStackTrace(); } } return result; } //联网获取json结果 private String getResponse(String uiMsg) { //访问网络 String result = null; if (uiMsg != null && uiMsg.length() > 0) { String basePath = "http://www.simsimi.com/requestChat?lc=zh&ft=1.0&req="; String path = basePath + uiMsg; HttpGet get = new HttpGet(path); HttpClient client = new DefaultHttpClient(); InputStream in = null; ByteArrayOutputStream baos = null; try { HttpResponse response = client.execute(get); if (response.getStatusLine().getStatusCode() == 200) { in = response.getEntity().getContent(); baos = new ByteArrayOutputStream(); byte[] b = new byte[1024]; int len; while ((len = in.read(b)) != -1) { baos.write(b, 0, len); } result = parserResult(new String(baos.toByteArray(), "utf-8")); } } catch (IOException e) { e.printStackTrace(); } finally { if (baos != null) { try { baos.close(); } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } } return result; }}
main.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="28sp" android:text="我问小黄鸡:" /> <EditText android:id="@+id/txt_ui_msg" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="28sp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:gravity="center" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="主线程发送消息给子线程" android:onClick="btnSendMsg" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="28sp" android:text="小黄鸡回复:" /> <TextView android:id="@+id/txt_return_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="28sp" /> </LinearLayout></LinearLayout>
0 0
- Android--Handler+Looper+MessageQueue+Thread线程之间的通信
- Android:Handler+Looper+MessageQueue+Thread(线程间的通信)随记
- 关于Android中由 Thread 、Handler、MessageQueue、Looper组成的“线程间通信 套件” 的分析
- Android线程间通信 Handler、Looper、MessageQueue
- Android线程通信机制,handler,looper,messageQueue的关系
- Android基于Handler、Looper、MessageQueue、ThreadLocal的跨线程通信
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- Thread,Looper,Handler,Message,MessageQueue之间的关系
- 学习Handler,Message,MessageQueue,Thread,Looper之间的关系
- Thread Looper MessageQueue Message Handler之间的关系
- Android笔记-MultiThreading in Android(1)-Thread,Looper,Handler,Message,MessageQueue之间的关系
- Android笔记-MultiThreading in Android(1)-Thread,Looper,Handler,Message,MessageQueue之间的关系
- Android笔记-MultiThreading in Android(1)-Thread,Looper,Handler,Message,MessageQueue之间的关系
- 线程 (Handler、Looper、MessageQueue和Thread的理解)
- Android中的Thread,MessageQueue,Looper,Message,Handler之间的关系图解
- Android中线程间通信原理分析:Looper,MessageQueue,Handler
- virtualbox装系统遇到的报错问题Unable to load R3 module D:\Program Files\Oracle\VirtualBox/VBoxDD.DLL (VBox
- ubuntu安装docker
- 10.Android ImageView ScaleType属性
- linux 基础命令
- JavaSE笔记
- Android--Handler+Looper+MessageQueue+Thread线程之间的通信
- js笔记
- Crazy android书中Fragment与Activity交互案例分析
- 蓝牙核心技术概述(三): 蓝牙协议规范(射频、基带链路控制、链路管理)
- 用EasyUI的一些感受
- chrome浏览器新发现
- Swift开发 函数的初探
- ld: i386 architecture of input file `exit.o' is incompatible with i386:x86-64 output
- python登录网页的两种方式