一.Message 、Looper、Handler之间的关系

1.系统发送的Message消息传送给Handler,Handler将Message放入自己的looper队列的底部
   然后再从Looper的顶部获取Message信息,并执行方法。

2.一个Handler只有一个Looper,一个Message仅与一个Handler交互,多个Handler可以与一个Looper交互。

3.主线程自带Hanlder和Looper

4.小技巧:为避免创建Message对象,所以调用Handler.obtainMessage()方法从公共池中获取Message,发送message:message.sendToTarget()。

//假设已经有一个Handler
mHandler.obtainMessage(int what,Obj obj)
.sendToTarget();

Message的解剖

Message最重要的三个变量:

what:用来描述信息,相当于Map的键值对的键。//因为有很多message发送给Handler所以Handler需要分辨

obj:存储对象,相当于Map的键值对的值。//Msg发送给Handler的对象

target:处理消息的Handler

arg1,arg2:存储数字,准备用来发送给Handler

Message在准备处理状态下,Handler负责处理行为。

注:通常对Message对象不是直接new出来的,只要调用handler中的obtainMessage方法来直接获得Message对象。

Looper的解剖

1.Looper的作用:是负责管理消息队列,负责消息的出列和入列操作。

2.流程:系统发送的Message消息传送给Handler,Handler将Message放入自己的looper队列的底部,然后再从Looper的顶部获取Message信息。

一个Handler只有一个Looper,多个Handler可以与一个Looper交互。

3.Looper的使用:Looper.myLooper():获取当前进程的looper对象,类似的 Looper.getMainLooper() 用于获取主线程的Looper对象。

Looper.prepare():创建Looper(主线程自带Looper,在子线程中使用创建Looper)

Looper.loop(); 让Looper开始工作,从消息队列里取消息,处理消息。

注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。

Handler的解剖

1.Handler主要有两个用途:首先是可以定时处理或者分发消息,其次是可以添加一个执行的行为在其它线程中执行

2.使用:子类需要继承Hendler类,并重写handleMessage(Message msg) 方法, 用于接受线程数据。

创建Handler的三种方法
//直接创建匿名类 缺点:默认为主进程的Looper
Handler mHandler = new Handler() {
@Override public void handleMessage(Message msg) {//覆盖handleMessage方法
switch (msg.what) {//根据收到的消息的what类型处理
case BUMP_MSG:
Log.v("handler", "Handler===="+msg.arg1);//打印收到的消息
break;
default:
super.handleMessage(msg);//这里最好对不需要或者不关心的消息抛给父类,避免丢失消息
break;
}
} //用new Handler(Looper looper,CallBack)
Handler myHandler = new Handler(new Callback(){
// 参数也可以为(this.getMainLooper(),new Callback(){})不写则默认为主线程的Looper,如果是在子线程中创建,Looper默认为子线程的Looper
//Handler不带参数的默认构造函数:new Handler(),实际上是通过Looper.myLooper()来获取当前线程中的消息循环,详见3
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
return false;
}
}); //子类继承Handler
class MyHandler extends Handler {
public MyHandler() {
} //默认为主线程的Looper public MyHandler(Looper L) {
super(L);
} //自定义的Looper // 子类必须重写此方法,接受数据
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Log。d("MyHandler", "handleMessage。。。。。。");
super。handleMessage(msg);
// 此处可以更新UI
Bundle b = msg。getData();
String color = b。getString("color");
MyHandlerActivity。this。button。append(color); }
}

3.在非主线程中Looper与Handler和Thread

在非主线程中直接new Handler() 错误,原因是非主线程中默认没有创建Looper对象,需要先调用Looper.prepare()启用Looper。

默认情况下,线程是没有消息循环的,所以要调用 Looper.prepare()来给线程创建消息循环,然后再通过,Looper.loop()来使消息循环起作用。

class LooperThread extends Thread

{
public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } };
Looper.loop();
}
}

作用:可实现主线程给子线程(非主线程)发送消息

:UI最好只能在主线程中运行。

二、HandlerThread

简介:继承自Thread,线程同时创建了一个含有消息队列的Looper,并对外提供自己这个Looper对象的get方法,这就是它和普通Thread唯一不同的地方。

使用

  1. 创建一个HandlerThread,即创建了一个包含Looper的线程。

    HandlerThread handlerThread = new HandlerThread("leochin.com");

    handlerThread.start(); //创建HandlerThread后一定要记得start()

  2. 获取HandlerThread的Looper(getLooper()是在start()之后使用的)

    Looper looper = handlerThread.getLooper();

  3. 创建Handler,通过Looper初始化

    Handler handler = new Handler(looper);

通过以上三步我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。

4.  关闭HandlerThread

handlerThread.quit();

子类继承HandlerThread时创建的小技巧:

class MyHandlerThread extends HandlerThread {
public MyHandlerThread(String name) {
super(name);
}//一定要定义当前Thread的名字
}

2.onLooperPrepare()是最适合创建内部Handler的地方

Looper、Hander、HandlerThread的更多相关文章

  1. logging、hashlib、collections模块

    一.hashlib模块(加密模块) 1.什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 , ...

  2. 【转】Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask

    方法一:(java习惯,在android不推荐使用) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { ...

  3. Android 消息机制 (Handler、Message、Looper)

    综合:http://blog.csdn.net/dadoneo/article/details/7667726 与 http://android.tgbus.com/Android/androidne ...

  4. android 之 Hnadler 、Message 、Looper

    Handler定义: 主要接受子线程发送来的数据,并用此数据配合主线程更新UI. 为什么要用Handler? 我们手机当中的很多功能或操作是不能都放在Activity当中的,比如下载文件.处理大量数据 ...

  5. Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等

    方法一:(java习惯,在android不推荐使用) 刚刚开始接触android线程编程的时候,习惯好像java一样,试图用下面的代码解决问题 new Thread( new Runnable() { ...

  6. Android线程之异步消息处理机制(二)——Message、Handler、MessageQueue和Looper

    异步消息处理机制解析 Android中的异步消息处理主要有四个部分组成,Message.Handler.MessageQueue和Looper. 1.Message Message是在线程之间传递的消 ...

  7. android开发笔记:Handler、Looper、MessageQueen、Message的关系

    一.什么是handler? 注:线程分为主线程(主线程又叫UI线程,只能有一个主线程)和子线程(可以有多个)Handler只能在主线程里运行 handler是Android给我们提供用来更新UI的一套 ...

  8. 深入了解Looper、Handler、Message之间关系

    深入了解Looper.Handler.Message之间关系 前言及简介 上个星期我们整个项目组趁着小假期,驱车去了江门市的台山猛虎峡玩了两个多钟左右极限勇士全程漂流,感觉真得不错,夏天就应该多多玩水 ...

  9. Android多线程源码学习笔记一:handler、looper、message、messageQueue

    最近在学习Android多线程相关知识的源码,现在把自己的笔记整理一下,写出来加深印象. Android多线程通讯的核心是handler.looper.message.messageQueue,这篇文 ...

随机推荐

  1. C的xml编程-libxml2(转)

    这里主要讲述libxml2在linux下的使用. (以下内容除了linux下的安装步骤是自己写的,其余均出自http://www.blogjava.net/wxb_nudt/archive/2007/ ...

  2. SQL Server T-SQL基础

    --数据库:数据库软件:mssqlserver,oracle,db2, ACCESS,SQLITE --数据库文件:分数据文件(MDF)和日志文件(log) 班级名称:(四期班训练营)长度可变,有中文 ...

  3. jquery中 append 和appendto的区别

    1. append(content)方法 方法作用:向每个匹配的元素内部追加内容. 参数介绍:content (<Content>): 要追加到目标中的内容. 用法示例: HTML代码为& ...

  4. String, StringBuilder 与StringBuffer的区别与联系

    1.区别 (1)String构建的对象不能改变,每次对String进行操作时,如两个String相加,需要新建一个String对象,然后容纳最终的结果. 而StringBuilder与StringBu ...

  5. mybatis常用jdbcType数据类型

    MyBatis 通过包含的jdbcType类型 BIT         FLOAT      CHAR           TIMESTAMP       OTHER       UNDEFINED ...

  6. javascript事件委托和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  7. wamp启动mysql的命令

    输入net start mysql提示服务名无效是因为在wamp集成安装中,mysql的服务名字是叫wampmysqld,可以用net start查看服务列表.所以命令启动mysql就应该输入net ...

  8. 引用 - PHP手册笔记

    引用是什么 PHP中的引用意味着,用不同的变量名访问同一变量内容,类似于Unix的文件名和文件本身(变量名是目录条目,变量内容是文件本身,即用不同的目录条目访问同一文件),可以看做Unix文件系统中的 ...

  9. 看懂这个sql 你的sql语句就掌握了

    某财务报表 USE [PB_AHTC]GO/****** Object: StoredProcedure [dbo].[JSPRO] Script Date: 12/10/2013 11:54:52 ...

  10. 关于C#的一点小知识 以后自己用

    项目过程中遇到C#代码的编写 上网查之后的结果 @html.ActionLink的几种参数格式 一 Html.ActionLink("linkText","actionN ...