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

近来找了一些关于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之前先初始化线程的消息队列。如下面的代码:

Java代码  

  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();

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

Java代码  

    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. }
时间: 2024-10-21 10:27:29

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

Thread+Handler 线程 消息循环(转载)

近来找了一些关于android线程间通信的资料,整理学习了一下,并制作了一个简单的例子. andriod提供了 Handler 和 Looper 来满足线程间的通信.例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的. 在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个事android的新 概念.我们的主线程(UI线程)就是一个消息循环的线程.针对这种消息循

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

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6905587 我们知道,Android应用程序是通过消息来驱动的,即在应用程序的主线程(UI线程)中有一个消息循环,负责处理消息队列中的消息.我们也知 道,Android应用程序是支持多线程的,即可以创建子线程来执行一些计算型的任务,那么,这些子线程能不能像应用程序的主线程一样具有消息循环呢?这 些子线程又能不能往应用程序的主线程中发送消息呢?本

【从源码看Android】03Android MessageQueue消息循环处理机制(epoll实现)

1 enqueueMessage handler发送一条消息 mHandler.sendEmptyMessage(1); 经过层层调用,进入到sendMessageAtTime函数块,最后调用到enqueueMessage Handler.java public boolean sendMessageAtTime(Message msg, long uptimeMillis) { MessageQueue queue = mQueue; if (queue == null) { RuntimeE

创建线程消息循环服务于动态连接库

因为动态连接库需要对DBT_DEVICEARRIVAL.DBT_DEVICEREMOVECOMPLETE等消息的处理,所以拿一个不太理想的usb-hid的dll来说明,不多说直接上代码 1 // 下列 ifdef 块是创建使从 DLL 导出更简单的 2 // 宏的标准方法.此 DLL 中的所有文件都是用命令行上定义的 WIN32USB_EXPORTS 3 // 符号编译的.在使用此 DLL 的 4 // 任何其他项目上不应定义此符号.这样,源文件中包含此文件的任何其他项目都会将 5 // WIN

Android Thread Handler UIHandler demos

extends:http://blog.csdn.net/superjunjin/article/details/7540064 序效果:为了显示如何用message传值的简单例子 例1,点击按钮,持续显示当前系统时间(bundle传值,耗时,效率低) 例2,点击按钮,progressbar持续前进(message方法传值,效率高,但只能传整型int和对象object) 例1,主activity  package com.song; import java.text.SimpleDateForm

Android Thread.UncaughtExceptionHandler异常消息捕获

public void uncaughtException(Thread thread, Throwable ex) { //处理异常 Log.e("崩溃",thread.getName()+ex.toString()); //发送到服务器 //dialog提醒 } 重写Application的onTerminate() 关闭整个程序后做的来操作:

Chromium on Android: Android系统上Chromium主消息循环的实现分析

摘要:刚一开始接触Chromium on Android时,就很好奇Chromium的主消息循环是怎么整合到Android应用程序中的.对于Android程序来说,一旦启动,主线程就会有一个Java层的消息循环处理用户输入事件等系统事件,而对Chromium来说,它有自己另一套消息循环的实现,这个实现有哪些特点,又将如何无缝整合到Android Java层的消息循环中去,正是本文所要讨论的话题. 原创文章系列,转载请注明原始出处为http://blog.csdn.net/hongbomin/ar

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

总结:刚开始接触一个Chromium on Android时间.很好奇Chromium主消息循环是如何整合Android应用. 为Android计划,一旦启动,主线程将具有Java消息层循环处理系统事件,如用户输入事件,而Chromium为,己还有一套消息循环的实现,这个实现有哪些特点.又将怎样无缝整合到Android Java层的消息循环中去,正是本文所要讨论的话题. 原创文章系列.转载请注明原始出处为http://blog.csdn.net/hongbomin/article/details

Android中利用Handler实现消息的分发机制(零)

在之前一篇介绍AsyncTask的文章中,我们在最后讲到,AsyncTask是利用Handler的消息异步处理机制,将操作结果,利用Message传回主线程,从而进行UI线程的更新的. 而在我们日常的开发工作中,Handler也是我们经常使用的类之一,那么Handler的主要作用是什么? Handler 的主要作用就是对消息(消息可以是我们想做的一些UI更新,也可以是其他的一些不可见的操作,如操作数据库等)的异步处理机制,而相信大家都了解异步的概念. 简单地说一下: 1)从程序的角度来看,就是当