`
苗振忠
  • 浏览: 56726 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Android 中消息处理机制-Looper、Handler、Thread(一)

 
阅读更多
最近项目中用到Handler,遇到点问题,找了一些资料,留着复习用。

原文地址:云中漫步http://my.unix-center.net/~Simon_fu/?p=652

熟悉Windows编程的朋友可能知道Windows程序是消息驱动的,并且有全局的消息循环系统。而 Android应用程序也是消息驱动的,按道理来说也应该提供消息循环机制。实际上谷歌参考了Windows的消息循环机制,也在Android系统中实现了消息循环机制。Android通过Looper、Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列和消息循环)。本文深入介绍一下Android消息处理系统原理。

Android系统中Looper负责管理线程的消息队列和消息循环,具体实现请参考Looper的源码。 可以通过Loop.myLooper()得到当前线程的Looper对象,通过Loop.getMainLooper()可以获得当前进程的主线程的 Looper对象。

前面提到Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。如下例所示:

  1. classLooperThreadextendsThread{
  2. publicHandlermHandler;
  3. publicvoidrun(){
  4. Looper.prepare();
  5. mHandler=newHandler(){
  6. publicvoidhandleMessage(Messagemsg){
  7. //processincomingmessageshere
  8. }
  9. };
  10. Looper.loop();
  11. }
  12. }


这样你的线程就具有了消息处理机制了,在Handler中进行消息处理。

Activity是一个UI线程,运行于主线程中,Android系统在启动的时候会为Activity创建一个消息队列和消息循环(Looper)。详细实现请参考ActivityThread.java文件。

Handler的作用是把消息加入特定的(Looper)消息队列中,并分发和处理该消息队列中的消息。构造Handler的时候可以指定一个Looper对象,如果不指定则利用当前线程的Looper创建。详细实现请参考Looper的源码。

Activity、Looper、Handler的关系如下图所示:

(图片不能上传:大哭

一个Activity中可以创建多个工作线程或者其他的组件,如果这些线程或者组件把他们的消息放入 Activity的主线程消息队列,那么该消息就会在主线程中处理了。因为主线程一般负责界面的更新操作,并且Android系统中的weget不是线程安全的,所以这种方式可以很好的实现Android界面更新。在Android系统中这种方式有着广泛的运用。

那么另外一个线程怎样把消息放入主线程的消息队列呢?答案是通过Handle对象,只要Handler对象以主线程的Looper创建,那么调用 Handler的sendMessage等接口,将会把消息放入队列都将是放入主线程的消息队列。并且将会在Handler主线程中调用该handler 的handleMessage接口来处理消息。

这里面涉及到线程同步问题,请先参考如下例子来理解Handler对象的线程模型:

1、首先创建MyHandler工程。

2、在MyHandler.java中加入如下的代码:

  1. packagecom.simon;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. importandroid.os.Message;
  5. importandroid.util.Log;
  6. importandroid.os.Handler;
  7. publicclassMyHandlerextendsActivity{
  8. staticfinalStringTAG="Handler";
  9. Handlerh=newHandler(){
  10. publicvoidhandleMessage(Messagemsg)
  11. {
  12. switch(msg.what)
  13. {
  14. caseHANDLER_TEST:
  15. Log.d(TAG,"Thehandlerthreadid="+Thread.currentThread().getId()+"\n");
  16. break;
  17. }
  18. }
  19. };
  20. staticfinalintHANDLER_TEST=1;
  21. /**Calledwhentheactivityisfirstcreated.*/
  22. @Override
  23. publicvoidonCreate(BundlesavedInstanceState){
  24. super.onCreate(savedInstanceState);
  25. Log.d(TAG,"Themainthreadid="+Thread.currentThread().getId()+"\n");
  26. newmyThread().start();
  27. setContentView(R.layout.main);
  28. }
  29. classmyThreadextendsThread
  30. {
  31. publicvoidrun()
  32. {
  33. Messagemsg=newMessage();
  34. msg.what=HANDLER_TEST;
  35. h.sendMessage(msg);
  36. Log.d(TAG,"Theworkerthreadid="+Thread.currentThread().getId()+"\n");
  37. }
  38. }
  39. }

在这个例子中我们主要是打印,这种处理机制各个模块的所处的线程情况。如下是我的机器运行结果:

  1. 09-1023:40:51.478:DEBUG/Handler(302):Themainthreadid=1
  2. 09-1023:40:51.569:DEBUG/Handler(302):Theworkerthreadid=8
  3. 09-1023:40:52.128:DEBUG/Handler(302):Thehandlerthreadid=1


我们可以看出消息处理是在主线程中处理的,在消息处理函数中可以安全的调用主线程中的任何资源,包括刷新界面。工作线程和主线程运行在不同的线程中,所以必须要注意这两个线程间的竞争关系。

上例中,你可能注意到在工作线程中访问了主线程handler对象,并在调用handler的对象向消息队列加入了一个消息。这个过程中会不会出现消息队列数据不一致问题呢?答案是handler对象不会出问题,因为handler对象管理的Looper对象是线程安全的,不管是加入消息到消息队列和从队列读出消息都是有同步对象保护的,具体请参考Looper.java文件。上例中没有修改handler对象,所以handler对象不可能会出现数据不一致的问题。

通过上面的分析,我们可以得出如下结论:

1、如果通过工作线程刷新界面,推荐使用handler对象来实现。

2、注意工作线程和主线程之间的竞争关系。推荐handler对象在主线程中构造完成(并且启动工作线程之后不要再修改之,否则会出现数据不一致),然后在工作线程中可以放心的调用发送消息SendMessage等接口。

3、除了2所述的hanlder对象之外的任何主线程的成员变量如果在工作线程中调用,仔细考虑线程同步问题。如果有必要需要加入同步对象保护该变量。

4、handler对象的handleMessage接口将会在主线程中调用。在这个函数可以放心的调用主线程中任何变量和函数,进而完成更新UI的任务。

5、Android很多API也利用Handler这种线程特性,作为一种回调函数的变种,来通知调用者。这样Android框架就可以在其线程中将消息发送到调用者的线程消息队列之中,不用担心线程同步的问题。

深入理解Android消息处理机制对于应用程序开发非常重要,也可以让你对线程同步有更加深刻的认识。以上是最近Simon学习Android消息处理机制的一点儿总结,如有错误之处请不吝指教。
分享到:
评论

相关推荐

    Android的消息处理机制--Message,MessageQueue

    Android的消息处理机制是其架构设计的重要组成部分之一,它确保了应用程序能够在多线程环境下高效稳定地运行。通过合理使用Message、MessageQueue、Handler和Looper,开发者可以轻松地实现线程间的通信,从而提升...

    Android线程模式(handler,thread,looper)

    1. **Handler**:Handler是Android消息处理机制的核心组件之一,它用于在不同的线程之间传递消息。一个Handler通常与Looper关联,发送的消息会被添加到Looper的消息队列中。主线程默认有一个Looper,而子线程如果...

    Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系 - Hongyang -

    【Android异步消息处理机制】深入理解Looper、Handler、Message三者关系 在Android系统中,异步消息处理机制是实现线程间通信和保证UI线程安全的关键组件。它涉及到了三个核心类:Looper、Handler和Message。这篇...

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

    本文详细介绍了Android中消息处理机制的核心组件Looper、MessageQueue和Handler的工作原理及其实现细节。理解这些概念有助于开发者更好地设计和实现多线程应用程序,提高程序的性能和用户体验。通过合理利用这些组件...

    Handler + Thread + Looper

    Handler、Thread和Looper之间的关系可以总结为:Handler是用来发送和处理消息的,它必须与一个Looper关联;Thread是消息处理的上下文,每个Thread可以有一个Looper;Looper则是在Thread中运行的消息循环,负责调度和...

    深入理解Android消息处理系统——Looper、Handler、Thread

    实际上谷歌参考了Windows的消息循环机制,也在Android系统中实现了消息循环机制。Android通过Looper  熟悉Windows编程的朋友可能知道Windows程序是消息驱动的,并且有全局的消息循环系统。而Android应用程序也是...

    Android消息处理机制Looper和Handler详解

    总结来说,Android的消息处理机制是一个高效且安全的异步通信方式,它保证了UI线程的流畅性,同时支持后台任务的执行。理解和熟练运用Looper、Handler和MessageQueue,对于开发高性能、响应迅速的Android应用至关...

    王栋栋_周报关于android异步消息处理机制handler_20190524.doc

    ### Android异步消息处理机制Handler详解 #### 一、Handler概念与作用 **Handler** 是Android框架提供的核心组件之一,主要用于实现线程间的消息传递,尤其是对于UI线程(主线程)与工作线程之间的通信至关重要。...

    Android多线程及异步任务消息处理机制 一 Handler的使用

    在Android开发中,多线程和异步任务处理机制是至关重要的,特别是在处理耗时操作如网络请求、数据库操作或大型数据计算时。本篇博文将聚焦于Android中的`Handler`机制,它是Android异步消息处理的核心组件。通过`...

    Android Looper使用介绍

    Android Looper 是 Android 操作系统中的一种机制,用于在单线程中创建消息循环,以便实现线程之间的通信和消息处理。Looper 对象通过 MessageQueue 来存放消息和事件,每个线程只能有一个 Looper 对象,-...

    Android的Message机制(Handler、Message、Looper)

    在Android开发中,消息机制是一个非常重要的概念,它由多个核心组件组成,包括`Handler`、`Message`、`Looper`等。这一机制支持了应用程序内部以及应用程序间的通信。下面将详细介绍这些组件的功能与协作方式。 ###...

    Android开发工程师面试题之handler详解。android程序员,android开发面试资料,详解

    在Android开发过程中,Handler是进行线程间通信的重要机制之一,尤其在实现异步任务更新UI等场景中扮演着关键角色。本篇文章将围绕Handler的工作原理、核心组件及其实现方式进行深入探讨,帮助读者更好地理解并掌握...

    Android消息机制Handler的工作过程详解

    5. **分发消息**:Looper从MessageQueue中取出消息,并找到对应Handler的`handleMessage()`方法进行处理。 6. **处理消息**:Handler的`handleMessage()`方法被调用,执行UI更新或其他操作。 注意,Looper一旦启动...

    Thread,Looper,Handler,Message,MessageQueue,MessagePool之间的关系

    在Android系统中,线程(Thread)、Looper、Handler、Message以及MessageQueue和MessagePool是实现异步消息处理机制的关键组件,它们共同构建了一个高效的事件驱动模型。这些组件的关系紧密,协同工作,使得Android...

    android计数器(Handler消息传递机制)

    在Android开发中,`Handler`消息传递机制是实现线程间通信的重要手段,尤其是在更新UI时。本项目中,我们看到一个简单的计数器应用,它利用`Handler`来每秒增加文本框中的数字,直到达到100为止。下面我们将深入探讨...

    Handler+Looper+MessageQueue

    这就是 Android 的异步处理机制,其中 Handler、Looper 和 MessageQueue 是关键组件,它们共同构成了 Android 线程间通信的基础。 1. **Handler**: Handler 是一个接口,用于发送和处理消息。它与 Looper 关联,...

    Android中消息机制

    总结来说,Android中的消息机制主要由Looper、Handler和Message Queue三个核心部分组成,它们共同协作实现了线程间的消息传递和处理。理解和掌握这一机制对于编写高效稳定的Android应用程序至关重要。

    android中异步消息处理

    本篇文章将详细介绍Android中的异步消息处理机制,包括Looper、Handler、MessageQueue的工作原理及其在实际应用中的作用。 #### 二、核心概念解析 ##### 1. Looper(循环) Looper是Android中用于管理消息循环的...

    Android Handler 异步消息机制的例子

    在Android开发中,Handler、Looper和Message是实现异步消息处理的关键组件,它们共同构成了Android的消息传递机制。这个机制使得应用程序能够优雅地处理UI线程与后台线程之间的通信,避免了因直接操作UI线程而导致的...

    Android Thread Handler

    **Handler** 是Android中用于线程间通信的一种机制,尤其在处理UI更新时非常关键。它的核心功能是发送和处理Message对象,这些Message由后台线程创建并发送到与主线程关联的Handler实例。Handler的工作原理主要涉及...

Global site tag (gtag.js) - Google Analytics