近来找了一些关于android线程间通信的资料,整理学习了一下,并制作了一个简单的例子。

 andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。

在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个事android的新 概念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handle,我们有消息循环,就要往消息循环里 面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,消息的的处理,把这些都封装在Handle里面,注意Handle只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。 
但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。 
  在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个是android的新概念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handler,我们有消息循环,就要往消息循环里面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,把这些都封装在Handler里面,注意Handler只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。

但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。

  一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列。如下面的代码:

  1. class ChildThread extends Thread {
  2. public void run() {
  3. /*
  4. * 创建 handler前先初始化Looper.
  5. */
  6. Looper.prepare();
  7. /*
  8. * 在子线程创建handler,所以会绑定到子线程的消息队列中
  9. *
  10. */
  11. mChildHandler = new Handler() {
  12. public void handleMessage(Message msg) {
  13. /*
  14. * Do some expensive operations there.
  15. */
  16. }
  17. };
  18. /*
  19. * 启动该线程的消息队列
  20. */
  21. Looper.loop();
  22. }
  23. }

当Handler收到消息后,就会运行handleMessage(…)的回调函数,可以在里面做一些耗时的操作。

最后完成了操作要结束子线程时,记得调用quit()来结束消息循环队列。

mChildHandler.getLooper().quit();

下面是一个线程间通信的小例子:

  1. /**
  2. *
  3. * @author allin.dev
  4. * http://allin.cnblogs.com
  5. *
  6. */
  7. public class MainThread extends Activity {
  8. private static final String TAG = "MainThread";
  9. private Handler mMainHandler, mChildHandler;
  10. private TextView info;
  11. private Button msgBtn;
  12. @Override
  13. public void onCreate(Bundle savedInstanceState) {
  14. super.onCreate(savedInstanceState);
  15. setContentView(R.layout.main);
  16. info = (TextView) findViewById(R.id.info);
  17. msgBtn = (Button) findViewById(R.id.msgBtn);
  18. mMainHandler = new Handler() {
  19. @Override
  20. public void handleMessage(Message msg) {
  21. Log.i(TAG, "Got an incoming message from the child thread - "
  22. + (String) msg.obj);
  23. // 接收子线程的消息
  24. info.setText((String) msg.obj);
  25. }
  26. };
  27. new ChildThread().start();
  28. msgBtn.setOnClickListener(new OnClickListener() {
  29. @Override
  30. public void onClick(View v) {
  31. if (mChildHandler != null) {
  32. //发送消息给子线程
  33. Message childMsg = mChildHandler.obtainMessage();
  34. childMsg.obj = mMainHandler.getLooper().getThread().getName() + " says Hello";
  35. mChildHandler.sendMessage(childMsg);
  36. Log.i(TAG, "Send a message to the child thread - " + (String)childMsg.obj);
  37. }
  38. }
  39. });
  40. }
  41. public void onDestroy() {
  42.       super.onDestroy();
  43. Log.i(TAG, "Stop looping the child thread's message queue");
  44. mChildHandler.getLooper().quit();
  45. }
  46. class ChildThread extends Thread {
  47. private static final String CHILD_TAG = "ChildThread";
  48. public void run() {
  49. this.setName("ChildThread");
  50. //初始化消息循环队列,需要在Handler创建之前
  51. Looper.prepare();
  52. mChildHandler = new Handler() {
  53. @Override
  54. public void handleMessage(Message msg) {
  55. Log.i(CHILD_TAG, "Got an incoming message from the main thread - " + (String)msg.obj);
  56. try {
  57. //在子线程中可以做一些耗时的工作
  58. sleep(100);
  59. Message toMain = mMainHandler.obtainMessage();
  60. toMain.obj = "This is " + this.getLooper().getThread().getName() +
  61. ".  Did you send me \"" + (String)msg.obj + "\"?";
  62. mMainHandler.sendMessage(toMain);
  63. Log.i(CHILD_TAG, "Send a message to the main thread - " + (String)toMain.obj);
  64. } catch (InterruptedException e) {
  65. // TODO Auto-generated catch block
  66. e.printStackTrace();
  67. }
  68. }
  69. };
  70. Log.i(CHILD_TAG, "Child handler is bound to - "+ mChildHandler.getLooper().getThread().getName());
  71. //启动子线程消息循环队列
  72. Looper.loop();
  73. }
  74. }
  75. }

Thread+Handler 线程 消息循环(转载)的更多相关文章

  1. Android----Thread+Handler 线程 消息循环(转载)

    近来找了一些关于android线程间通信的资料,整理学习了一下,并制作了一个简单的例子. andriod提供了 Handler 和 Looper 来满足线程间的通信.例如一个子线程从网络上下载了一副图 ...

  2. Android应用程序线程消息循环模型分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是 ...

  3. Android之MessageQueue、Looper、Handler与消息循环

    在android的activity中有各种各样的事件,而这些事件最终是转换为消息来处理的.android中的消息系统涉及到: *  消息发送 *  消息队列 *  消息循环 *  消息分发 *  消息 ...

  4. Android的消息循环机制 Looper Handler类分析

    Android的消息循环机制 Looper Handler类分析 Looper类说明   Looper 类用来为一个线程跑一个消息循环. 线程在默认情况下是没有消息循环与之关联的,Thread类在ru ...

  5. Android线程消息通信(一)

    Android在Java标准线程模型的基础上,提供了消息驱动机制,用于多线程之间的通信.基于消息驱动机制的线程通信模型陈伟线程消息通信.在标准线程模型中,线程执行完毕后便退出,而Android扩展了线 ...

  6. Chromium on Android: Android在系统Chromium为了实现主消息循环分析

    总结:刚开始接触一个Chromium on Android时间.很好奇Chromium主消息循环是如何整合Android应用. 为Android计划,一旦启动,主线程将具有Java消息层循环处理系统事 ...

  7. System、应用程序进程的Binder线程池和Handler消息循环

    首先看一张Android系统启动流程图:

  8. [转]Handler MessageQueue Looper消息循环原理分析

    Handler MessageQueue Looper消息循环原理分析   Handler概述 Handler在Android开发中非常重要,最常见的使用场景就是在子线程需要更新UI,用Handler ...

  9. Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面

    Android应用的开发过程中需要把繁重的任务(IO,网络连接等)放到其他线程中异步执行,达到不阻塞UI的效果. 下面将由浅入深介绍Android进行异步处理的实现方法和系统底层的实现原理. 本文介绍 ...

随机推荐

  1. [android]如何让TextView使用超链接

    找了很多网址,最后是这个有说到. 总的做法是: 1.(当然也可以从Res中获取.) tv.setText(Html.fromHtml("<a href=\"http://ww ...

  2. Android学习笔记一

    一.eclipse中的十大快捷键: 1. ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的 ...

  3. CF 577C Vasya and Petya's Game

    题意:一个游戏,A童鞋在1~n的范围里猜一个数,B童鞋询问一个集合,A童鞋要对集合里每个数做出回答,他猜的数能否给整除,B要通过这些答案得到A猜的数,最少需要猜哪些数? 解法:一个数可以由若干个质数的 ...

  4. Conversion to Dalvik format failed: Unable to execute dex: null

    [2013-11-19 14:18:48 - Dex Loader] Unable to execute dex: java.nio.BufferOverflowException. Check th ...

  5. 【剑指offer 面试题15】链表中倒数第K个结点

    思路: 定义两个指针同时指向head,第一个指针先走K-1步,随后二个指针同时移动,当第一个指针到末尾处时,第二个指针所指向的即为倒数第K个结点. #include <iostream> ...

  6. 《Python 学习手册4th》 第十三章 while和for循环

    ''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书) “重点 ...

  7. JavaScript如何判断参数为浮点型

    在codewars里,确实可以学到很多很酷的方法,例如这一次的题目是判断数字是否为浮点型.我一开始是想有没有原生的js方法,像isNaN(),isFinite(),在前者Infinity是不属于NaN ...

  8. ubuntu下修改时区

    使用一个虚拟机服务,其时区设置的为格林兰标准时区,我北京时区在东八区,较其快八个小时. 修改时区需要执行 tzselect 一步步选择下来,注意确认后的information Therefore TZ ...

  9. iPhone各种尺寸

    iPhone 6 Plus      736x414 points      2208x1242 pixels     3x scale     1920x1080 physical pixels   ...

  10. C++问题-Qt Visual Studio Add-in

    问题现象:用VS打开其他人的项目提示如下:Qt Visual Studio Add-in...中间全TMD的英文,我就省略...QT版本不对,需要修改QT版本. 问题原因:占时不明,因为我是开发Del ...