线程通讯问题

(主要用到了Handler类,Looper类和Message类以及MessageQueue)

在Android中主线程如何向子线程中发送消息的问题。让我们来想想,这其中的过程,无非就是创建一个Handler对象,然后一个线程发消息,另一个接收消息嘛。下面是接下来需要涉及到的几个重要类。我们可以把它们想象成以下几个内容。 信息队列管家(Looper); 消息队列(MessageQueue); 消息(Message):可以多个; 信息工人(Handler):可以多个;

下面主要介绍下这几个类:

1.Looper类,Looper它就像一个消息队列(MessageQueue)的管家(Looper),一个消息队列只有一个信息管家,并且管理整个消息队列,而一个消息队列内可以容纳多个消息(Message),而信息处理者(Handler)也可以有多个,消息队列处理者派遣他们向消息队列中存储或取出消息后执行任务;是用来为一个线程开启一个消息队列,通常情况下,Android下新开启的线程没有开启消息队列的(除了主线程外),主线程系统会默认为其开启一个消息队列;looper是通过MessageQueue来存放消息队列的,一个线程只有一个looper对象。

2.Message类 是定义一个Messge包含必要的描述和属性数据,并且此对象可以被发送给android.os.Handler处理。属性字段:arg1、arg2、what、obj、replyTo等;其中arg1和arg2是用来存放整型数据的;what是用来保存消息标识的;obj是Object类型的任意对象;replyTo是消息管理器,会关联到一个handler,handler就是处理其中的消息。通常对Message对象不是直接new出来的,只要调用handler中的obtainMessage方法来直接获得Message对象。

3.Handler类,通过handler与looper来实现交互,通过可以把handler看做是looper的一个接口,用来向指定的looper发送消息和处理消息。Handler主要有两个用途:首先是可以定时处理或者分发消息,其次是可以添加一个执行的行为在其它线程中执行,对于Handler中的方法,可以选择你关心的操作去覆盖它,处理具体的业务操作,常见的就是对消息的处理可以覆盖public void handleMessage(参数)方法,可以根据参数选择对此消息是否需要做出处理。

注意:默认情况下,handler会与线程内定义的Looper绑定在非主线程中定义Handler=new Hander()会报错,原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。  还有就是写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,looper才会中止,其后的代码才能得以运行。

Message机制原理示意图:

Activity、IntentReceiver   <------>  Handler<----->  Looper<----->  MessageQueue

下面是一个实例来实现主线程内发送消息到线程类内:

  1. package com.example.xx;

  2. import android.os.Bundle;

  3. import android.os.Looper;

  4. import android.os.Message;

  5. import android.app.Activity;

  6. import android.view.View;

  7. import android.view.View.OnClickListener;

  8. import android.widget.Button;

  9. public class MainActivity extends Activity {

  10. Private static final int MAKE = 0x1;

  11. Private Button button;

  12. @Override

  13. protected void onCreate(Bundle savedInstanceState) {

  14. super.onCreate(savedInstanceState);

  15. ...  //这里是简单的获取组件

  16. final LooperThread looperThread = new LooperThread();

  17. looperThread.start();

  18. button.setOnClickListener(new OnClickListener() {

  19. @Override

  20. public void onClick(View v) {

  21. // TODO Auto-generated method stub

  22. String info=”这是内容";

  23. Message msMessage = new Message();

  24. msMessage.what=MAKE;

  25. msMessage.obj =info;

  26. looperThread.handler.sendMessage(msMessage);

  27. }

  28. });

  29. }

  30. }

    下面是线程类,用来接收主线程内发送过来的消息

    1. package com.example.xx;

    2. import android.os.Handler;

    3. import android.os.Looper;

    4. import android.os.Message;

    5. import android.util.Log;

    6. public class LooperThread extends Thread {

    7. public static Handler handler;

    8. @Override

    9. public void run() {

    10. // TODO Auto-generated method stub

    11. super.run();

    12. Looper.prepare();

    13. handler = new Handler() {

    14. @Override

    15. public void handleMessage(Message msg) {

    16. // TODO Auto-generated method stub

    17. If( Msg.what == MAKE){

    18. System.out.println("--" + msg.obj.toString());

    19. }

    20. }

    21. };

    22. Looper.loop();

    23. }

    24. }

最新文章

  1. macOS sierra 10.12 Cocoapods 私有库
  2. 一个老菜鸟所理解的UX及产品流
  3. 将PostGIS转化为GeoJSON
  4. java 28 - 7 JDK8的新特性 之 接口可以使用方法
  5. Delphi中线程类TThread实现多线程编程1---构造、析构……
  6. Android -- 简单广播接收与发送(2)--动态注册广播接收器
  7. console.log的应用
  8. C++中尖括号和引号的区别---转载
  9. java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
  10. 微软在MSDN中更新了Win8.1批量授权版镜像(中文版更新完毕&amp;版本说明)
  11. Cube(hd1220)
  12. Java的关键字和标识符
  13. C++primer 9.49
  14. 学习java的感受
  15. bootstrap 基础(二)
  16. mpvue-编写微信小程序总结
  17. Ubuntu基础教程——安装谷歌Chrome浏览器
  18. [转]Blue Prism Login Agent 使用指导手册
  19. Activiti开发案例之activiti-app更换数据源
  20. Mysql生产指定时间段随机日期函数

热门文章

  1. 15.selenium_case02
  2. 鼠标右键打开命令行cmd(管理员身份)
  3. 18.JAVA经典编程题(50题及答案)
  4. day25 Python __setattr__
  5. linux注释多行
  6. oracle RAC 查询告警日志位置
  7. Spring Security(一):官网向导翻译
  8. &lt;网络编程&gt;套接字介绍
  9. 【LOJ 2004】「SDOI2017」硬币游戏
  10. Luogu P1967 货车运输