总结一下Handler与Looper,MessageQueue的关系,并实现自定义与子线程相关的Handler。

一、Handler与Looper,MessageQueue的关系

它们之间的关系其实就是下面的三条说明:

(1)Looper:相当于消息的载体

• 它的内部有一个消息队列,也就是MessageQueue,Handler发送的所有消息都会走向这个消息队里。

• 它的Looper.loop方法是一个死循环,不断的从消息队列MessageQueue中取出消息。如果有消息存在就处理该消息,否则就阻塞。

(2)MessageQue:就是一个消息队列,可以向其中添加消息并处理消息。

(3)Handler其实就是发送消息处理消息的封装。它与Looper相关联,也就是说在Handler的内部可以找到Looper,找到了Looper就找到了相应的消息队列。因此Handler发送的消息都会走向MessageQueue。

对上面三点说明做一个总结,其实就是:

Handler负责发送消息和接收Looper传过来的消息,并根据消息处理相应逻辑
Looper负责接收Handler发送过来的消息,并将该消息回传给Handler自己。
而MessageQueue只是相当于一个消息容器

经过上面的说明,对android中的Handler消息处理机制应该有了一个大致的了解了。那么你肯定还有疑问,为什么处理消息要严格这样子做呢?这个问题其实就是为什么不能在子线程中更新UI的问题。下面就是原因。

为什么不能在子线程中更新UI

我们假设可以在子线程更新UI,那么就会出现这样子的一种况:其中一个子线程更新界面还没有完成,另外一个子线程就又去更新UI了,这样子会造成子UI界面错乱。那么你可能会说,我们可以实行加锁机制啊,让更新UI的代码不能并发执行。如果每一个子线程都加锁,那么毫无疑问程序的性能将会大大下降。因此主要的原因总结起来就是两点:

(1)为了防止界面错乱

(2)为了防止程序性能下降

因此android不允许在子线程中更新UI。为了解决这个这个问题,android就设计出这样子的一套消息处理机制,让我们尽管在子线程中发送更新UI的消息,而不用去关心多线程问题。在主线程的消息队里中采取轮询更新处理。

二、自定义与子线程关联的Handler

了解了Handler与Looper,MessageQueue后,我们可以实现自定义的Handler,该Handler与子线程关联(注意我们创建的默认Handler都是与主线程,即UI线程关联的,因为没有指定Looper,因此如果Looper不存在是不能创建Handler的)。下面我们就来简单实现这个自定义的Handler。新建一个项目,只需要修改它的MainActiivty代码即可,如下:

 package com.example.handldertest;

 import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.widget.TextView; public class ThreadHandlerActivity extends Activity{ //创建子线程
class MyThread extends Thread{
private Handler handler;//与该子线程关联的Handler
public void run() { Looper.prepare();//创建该子线程的Looper
handler = new Handler(){//默认与当前线程关联
public void handleMessage(android.os.Message msg) {
Log.d("当前子线程是----->", Thread.currentThread()+"");
};
}; Looper.loop();//只要调用了该方法才能不断循环取出消息
}
} private TextView tv;
private MyThread thread; private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
Log.d("当前主线程是----->", Thread.currentThread()+"");
};
}; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tv = new TextView(this);
tv.setText("Handler实验");
setContentView(tv); thread = new MyThread();
thread.start();//千万别忘记开启这个线程
try {
Thread.sleep(2000);//主线程休眠2秒
} catch (InterruptedException e) {
e.printStackTrace();
}
//下面用子线程的Handler发送消息
thread.handler.sendEmptyMessage(1);
//下面是主线程发送消息
mHandler.sendEmptyMessage(1);
} }

在程序的MyThread类中,我们首先创建自己的Looper,然后使用Handler的无参数构造器(无参构造器默认的是与当前线程相关联)。最后千万要记得调用Looper.loop方法,这样子才能让消息队列循环轮询(即是个死循环)。然后在onCreate方法中让主线程休眠2秒后(主要是为了便于观看结果),再让子线程的handler发送消息,当然我了区别的观察结果,我们也建立了一个主线程的Hander,即mHandler,也让它发送了消息。打印的结果如下:

通过打印结果,我们发现打印出来的当前线程ID是不一样的,充分说明handler是与创建的子线程相关联的。总结一下吧。

实现与子线程关联的Handler,必须要:

1. 必须先创建Looper,调用Looper.prepare方法即可
2. 实例化Handler,与之关联
3. 调用Looper.loop方法,实现循环不断读取消息

上面三步是要放在run方法中编写的。

Handler与Looper,MessageQueue的关系的更多相关文章

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

    解析Android消息处理机制 ——Handler/Thread/Looper & MessageQueue Keywords: Android Message HandlerThread L ...

  2. Android Handler处理机制 ( 三 ) ——Handler,Message,Looper,MessageQueue

    在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长时间的任务后做出相应的通知 handler基本使用: 在主线程中,使用handler很简单,new一个Handle ...

  3. Android Handler处理机制 ( 一 )(图+源码分析)——Handler,Message,Looper,MessageQueue

    android的消息处理机制(图+源码分析)——Looper,Handler,Message 作为一个大三的预备程序员,我学习android的一大乐趣是可以通过源码学习 google大牛们的设计思想. ...

  4. Android Handler处理机制 ( 二 ) ——Handler,Message,Looper,MessageQueue

    Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...

  5. 讲讲Handler+Looper+MessageQueue 关系

    Handler+Looper+MessageQueue这三者的关系其实就是Android的消息机制.这块内容相比开发人员都不陌生,在面试中,或者日常开发中都会碰到,今天就来讲这三者的关系. 概述: H ...

  6. Handler Looper MessageQueue 之间的关系

    Handler Looper MessageQueue 之间的关系 handler在安卓开发中常用于更新界面ui,以及其他在主线程中的操作.内部结构大概图为: 1.handler持有一个Looper对 ...

  7. Android开发 之 理解Handler、Looper、MessageQueue、Thread关系

    本文转自博客:http://blog.csdn.net/he90227/article/details/43567073 一. 图解与概述 首先Android中 的每一个线程都会对应一个Message ...

  8. 深入理解Message, MessageQueue, Handler和Looper

    做过Android的都知道Message, MessageQueue, Handler和Looper,但知道不代表你理解它们.有时觉得用得很顺手,但Android怎么实现又说不上来,总觉得似懂非懂.不 ...

  9. Android消息机制:Looper,MessageQueue,Message与handler

    Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Mes ...

随机推荐

  1. iOS-验证码倒计时60秒

    一. 要求 1.点击获取验证码按钮,60秒倒计时,按钮变成不可点击状态,按钮文字变成倒计时的秒数. 2.当倒计时为0的时候,释放掉定时器NSTimer,按钮变成可以点击状态,按钮文字变成"获 ...

  2. Android 学习笔记之Volley开源框架解析(四)

    学习内容: 1.NetWorkDispatcher网络请求线程调度... 2.NetWork网络请求抽象类... 3.BasicNetWork网络请求抽象类的具体实现... 4.NetWorkResp ...

  3. “康园圈--互联网+校园平台“项目之sprint1总结

    一.团队成员     梁植淋,官郅豪,纪焓,詹耀海 二.目前进度       在全体组员的努力下,目前完成了项目的<设计方案书>.<功能需求书>.框架搭建.项目部署文档. 并成 ...

  4. springMVC注解@initbinder日期类型的属性自动转换

    在实际操作中经常会碰到表单中的日期 字符串和Javabean中的日期类型的属性自动转换, 而springMVC默认不支持这个格式的转换,所以必须要手动配置, 自定义数据类型的绑定才能实现这个功能. 一 ...

  5. MVC bundle(包扎)CSS或是JS文件

    以前写asp.net网页时,会在<head>节点中引用很多样式文件或是javascript文件,如下图左大括号的引用语句. 现在在MVC应用程序中,可以使用使用Bundle来捆一起, 在S ...

  6. 【iOS】编译静态库

    与java和.net一样,objc也由类库的概念,不过在在objc上一般叫库,库表示程序代码集合,可以共享给其他程序使用,库是编译后的二进制文件,因此不能看到源代码,多用于一些开放sdk(如百度地图s ...

  7. 不可或缺 Windows Native (5) - C 语言: 数组

    [源码下载] 不可或缺 Windows Native (5) - C 语言: 数组 作者:webabcd 介绍不可或缺 Windows Native 之 C 语言 数组 示例cArray.h #ifn ...

  8. 在phpwind内容页使用百度分享进行图片分享

    在phpwind内容页使用百度分享进行图片分享时,百度分享默认提取到的图片不一定是主题正文内容中的图片,需要使用百度提供的配置机制自行调整. 整个代码添加的位置在此不论,主要原理是在主题正文区域提取图 ...

  9. 泛函编程(21)-泛函数据类型-Monoid

    Monoid是数学范畴理论(category theory)中的一个特殊范畴(category).不过我并没有打算花时间从范畴理论的角度去介绍Monoid,而是希望从一个程序员的角度去分析Monoid ...

  10. netty Failed to submit an exceptionCaught() event异常

    最近测试netty开发的服务端应用在关闭时,出现下列异常: ->###WARN#########nioEventLoopGroup-3-2###io.netty.util.internal.lo ...