Android Handler (Loop MessageQueue) 解析

转载 2013年12月03日 18:07:47

最近在写代码的时候,突然间碰到loop这个东西,所以上网找了一下文件,看到有一个老兄写的还不错,这里当做笔记一样记下来,也分享给大家看看。

1、Handler用途
2、Handler方法简析
3、Handler Loop MessageQueue原理分析  
4、Handler案例代码

1、Handler 用途
 
       Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出,然后对消息进行处理,就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。

2、Handler方法简析
    2.1、发送消息   send****
             sendEmptyMessage(int),发送一个空的消息;
        sendMessage(Message),发送消息,消息中可以携带参数;
        sendMessageAtTime(Message, long),未来某一时间点发送消息;
        sendMessageDelayed(Message, long),延时Nms发送消息。
    
   2.2、延迟发送消息post****()
            post(Runnable),提交计划任务马上执行;
  postAtTime(Runnable, long),提交计划任务在未来的时间点执行;
       postDelayed(Runnable, long),提交计划任务延时多少毫秒再执行。


3、Handler消息机制原理分析
       MessageQueue指的是消息队列,存放消息的队列,按照first in first out的规则执行,每个线程()只拥有一个MessageQueue,在创建Looper对象的时候会创建一个MessageQueue对象,每个MessageQueue都会对应一个Handler。
       上面介绍到的handler发送消息的两种方法:send和post发送消息給MessageQueue,按照fifo方式执行
       sendMessage发送的是Message对象,会被Handler的handleMessage()函数处理
       post 发送的是Runnable对象,会自己执行
 
       Message --消息对象, MessageQueue中存放的对象。一个MessageQueue中可以存放多个Message对象,通过Message.obtain()或者Handler.obtainMessage()获取message对象,但是不是直接创建对象,而是先看看消息池中看看有没有可用的Message实例,再用给定参数创建一个Message对象,使用removeMessage()方法将Message从MessageQueue当中移除,顺便将其放回消息队列中。

       消息可以理解成线程和线程之间沟通的信息,后台线程完成一个处理以后需要更新UI,则发送一个Message对象給UI线程,里面包含一些刷新信息

       Looper对象-- 操作MessageQueue的对象
    
       一个Looper对象对应一个MessageQueue,通过Looper.myLooper()可以获取当前线程的Looper对象,Looper从MessageQueue中取出Message然后交给handler的HandleMessage()进行处理,处理完成以后,调用Message.recycle()将其放入消息池中。Looper是每个线程中的MessageQueue操作者,在Android中没有全局的MessageQueue,但是android会自动为UI线程创建一个MessageQueue,但是子线程却不会。所以你调用Looper.getMainLooper()可以得到Looper对象,但是Looper.myLooper()却有可能获得null的Looper对象

      Handler 消息的处理者
      
      Handler负责封装Message对象,然后调用sendMessage()方法将message放入MessageQueue队列中,当这条消息被取出的时候会调用对应的Handler对象的handleMessage()方法进行处理,Handler可以共享一个Looper和MessageQueue

      示例代码:普通线程中handler給UI线程发送消息更新android界面

package com.example.handlertest; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.widget.TextView; public class MainActivity extends Activity { private static final int REFRESH_UI = 1; private TextView tvShow; private MyThreadHandler myThreadHandler; private UIHandler uiHandler; private HandlerThread handlerThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); //创建刷新UI的handler对象 uiHandler = new UIHandler(); //创建handler线程 handlerThread = new HandlerThread("spendtimes"); handlerThread.start(); //获取handler线程的消息队列,用于创建我自己的handler myThreadHandler = new MyThreadHandler(handlerThread.getLooper()); //发送一条空消息启动操作,此时消息被发送至线程中的消息队列 myThreadHandler.sendEmptyMessage(1); } private void initView() { tvShow = (TextView) findViewById(R.id.show_res); } class MyThreadHandler extends Handler{ public MyThreadHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { if(msg.what == 1) { //耗时处理操作 try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } StringBuilder sb = new StringBuilder(); sb.append(tvShow.getText().toString()); sb.append(" dealwith thread"); //操作完成以后,调用主线程handler发送刷新消息,此时消息被加入UI线程消息队列,等待被执行 //将处理结果保存到obj对象中,随消息发送出去 Message message = new Message(); message.obj = sb.toString(); message.what = REFRESH_UI; uiHandler.sendMessage(message); } } } class UIHandler extends Handler{ @Override public void handleMessage(Message msg) { if(msg.what == REFRESH_UI) { //从消息中获取返回结果 String res = (String) msg.obj; tvShow.setText(res); } } } }

xml文档如下

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <TextView android:id="@+id/show_res" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:text="hello_world" /> </RelativeLayout>


上面一段代码实现了在普通线程中处理耗时操作完成以后,然后給UI线程发送消息,然后更新UI界面

其中核心流程如下: 
       首先获取一个线程中的MessageQueue,这里我们采用创建一个ThreadHandler,获取这个线程的MessageQueue队列,然后绑定到我们自定义的MyThreadHandler,此时MyThreadHandler的handleMessage方法都是在线程中处理的,不会卡死主进程,当处理完成以后,我们调用主线程中的uiHandler向UI线程中的MessageQueue中发送结果消息,等到主线程从队列中取出消息进行处理,更新UI界面,这样就完美的处理异步操作

Android菜鸟的成长笔记(12)——Handler、Loop、MessageQueue

当一个程序第一次启动时,Android会启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如按键事件、触屏事件、绘图事件,主线程也被称为UI线程。 UI的操作只能是通过主线...

android基础--Handler,Loop,MessageQueue

Handler可以声明在主线程可以声明在新开的线程,只不过在新开的线程定义handler要自己创建一个Looper对象,并通过prepare()启动它。在ui线程中系统已经初始化了一个Looper对象...

第五课:Android中Handler、Loop、MessageQueue的工作原理和使用方法

Message:Handler接收和处理的消息对象。 Looper:

Android---28---Handler、Loop、MessageQueue的工作原理:

Handler、Loop、MessageQueue的工作原理: 先介绍一下这几个组件: Message:Handler接收和处理的消息对象 Looper:读取MessageQueue中的消息,并将读到...

Handler,Loop,Message,MessageQueue,ThreadLocal关系详解

一直对handler机制一知半解,花了两天时间对handler从信息发送到接收,handler机制的整个过程就是handler发送信息给looper,looper在适当的时候通过handler的dis...

Handler、Loop、MessageQueue的工作原理

转载:http://blog.csdn.net/itachi85/article/details/8035333 andriod提供了Handler 和 Looper 来满足线程间的通信。Han...

Handler、Loop、MessageQueue的工作原理<温故知新>

为了更好地理解Handler的工作原理,说下与Handler一起工作的几个组件。 1. MessageQueue:Handler接收和处理的消息对象。 2.Looper:每个线程只能拥有一个Loope...

Handler, Loop, MessageQueue的工作原理

Message: 消息对象 Looper: 每个线程拥有一个looper,负责读取MessageQueue中的Message,然后把消息发送给发送消息的Handler处理。 MessageQueu...
  • kui2015
  • kui2015
  • 2015年11月27日 17:05
  • 270

Handler、Loop和MessageQueue

一、Android之线程信使 二、

解析Android消息处理机制:Handler/Thread/Looper & MessageQueue

解析Android消息处理机制——Handler/Thread/Looper & MessageQueue 田海立@CSDN2011/07/12 Keywords: Android Message H...
  • thl789
  • thl789
  • 2011年07月12日 23:51
  • 23977
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android Handler (Loop MessageQueue) 解析
举报原因:
原因补充:

(最多只允许输入30个字)