Android中的Handler的机制与用法详解

android的handler 是一个神奇东西,处理异步消息的时候,我们离不开他.那么他的具体的介绍是什么了?

一:Handler基本概念:
Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分逐个的在消息队列中将消息取出,然后对消息进行出来,就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。
Handler 是 Android 给我们提供来更新 UI 的一套机制,也是一套消息处理的机制,我们可以发送消息,也可以通过它来处理消息,Handler 在我们的 framework 中是非常常见的。
Android 在设计的时候,就封装了一套消息创建、传递、处理机制,如果不遵循这样的机制就没有办法更新 UI 信息,就会抛出异常信息。

二:了解几个概念
很多Android初学者对Android 中的Handler不是很明白,其实Google参考了Windows的消息处理机制,在Android系统中实现了一套类似的消息处理机制。

在下面介绍Handler机制前,首先得了解以下几个概念:

Message 消息,理解为线程间通讯的数据单元。例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程。
Message Queue 消息队列,用来存放通过Handler发布的消息,按照先进先出执行。
Handler Handler是Message的主要处理者,负责将Message添加到消息队列以及对消息队列中的Message进行处理。
Looper 循环器,扮演Message Queue和Handler之间桥梁的角色,循环取出Message Queue里面的Message,并交付给相应的Handler进行处理。
线程 UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。

三:Handler的用法
3.1对于handler的常用的一些方法有:
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)

以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

使用 Handler 在子线程中向 UI 线程发送一个消息进行 UI 的更新
创建一个 Message, Message msg = new Message(); msg.arg1 = 88;
handler.sendMessage(msg); msg.obj = xxx; 可以传递一个对象
当然不一定要用 new 一个 Message,也可以复用系统的 message 对象 Message msg = handler.obtainMessage();

3.2 传递 Callback 对象

Callback 用于截获 handler 发送的消息,如果返回 true 就截获成功不会向下传递了。

public Handler mHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), “HandleMessage 1”, Toast.LENGTH_SHORT).show();
return true;
}
}) {
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), “handleMessage 1”, Toast.LENGTH_SHORT).show();
};
}
上面的示例中,第一个有返回值的 handlerMessage 方法是 Callback 的回调,如果返回true,则不执行下面的 handlerMessage 方法,从而达到拦截 handler 发送的消息的目的,如果返回 false,则会继续执行 handlerMessage 方法。

四:Handler原理
4.1 Android 为什么要设计只能通过 Handler 机制更新 UI 呢?

最根本的目的就是解决多线程并发的问题,假设在一个 Activity 当中,有多个线程去更新 UI,并且对更新的 UI 的操作进行枷锁处理的话又会产生什么样的问题呢? 那就是性能下降,Handler 通过消息队列,保证了消息处理的先后有序。

鉴于以上问题的考虑,Android 给我们提供了一套更新 UI 的机制,我们只要使用一套机制就好,所有的更新 UI 的操作都是在主线程中轮询处理。

4.2 Handler 的原理是什么?
Handler 封装了消息的发送(主要包括消息发送给谁) Looper:
内部包含一个消息队列也就是 MessageQueue,所有 Handler 发送的消息都走向这个队列。
Looper.loop()方法,就是一个 for 死循环,不断的从 MessageQueue 取消息,如果有消息就处理消息,没有消息就阻塞。
MessageQueue,就是一个消息队列,可以添加消息,处理消息。
Handler 也不难,比较简单,在构造 Handler 时候内部会跟 Looper 进行关联,通过 Looper.myLooper() 获取到 Looper,找到 Looper 也就找到了 MessageQueue。在 Handler 中发送消息,其实是向 MessageQueue 队列中发送消息。
4.3 Handler 与 Looper、MessageQueue 的关系
这一小结:handler 负责发送消息,Looper 负责接收 Handler 发送消息,并直接把消息回传给 handler 自己,MessageQueue 就是一个存储消息的容器。
下图展示了 Handler、MessageQueue、Looper 之间是如何协作的。
这里写图片描述
五:Handler 与子线程
5.1 自定义与线程相关的 Handler

class MyThread extends Thread {
public Handler handler;
@Override
public void run() {
Looper.prepare(); //new 一个Looper对象
handler = new Handler() { //拿到当前线程的 Looper 对象
@Override
public void handlerMessage(Message msg) {
// TODO Auto-generated method stub
System.out.println(“current thread:” + Thread.currentThread());
}
};
Looper.loop();//开始死循环处理消息
};
}
一般 UI 主线程中不要执行一些耗时的操作,这样就可以通过子线程消息来处理耗时操作。

5.2 HandlerThread是什么?

HandlerThread 继承于 Thread,所以它本质就是个 Thread。与普通的 Thread 的差别就在于,它有个 Looper 成员变量。这个 Looper 其实就是对消息队列以及队列处理逻辑的封装,简单来说就是消息队列+消息循环。

当我们需要一个工作线程,而不是把它当作一次性消耗品,用过即废的话,就可以使用它。

private Handler mHandler = null;
private HandlerThread mHandlerThread = null;

private void sendRunnableToWorker(Ruannable run) {
if (null == mHandlerThread) {
mHandlerThread = new HandlerThread(“WorkerThread”);
// 给工作者线程低优先级
mHandlerThread.setPriority(Thread.MIN_PRIORITY);
mHandlerThread.start();
}
if (null == mHandler) {
mHandler = new Handler(mHandlerThread.getLooper());
}
mHandler.post(run);
}
6. 主线程与子线程之间的信息交互

//创建主线程的Handler
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
Message mssage = new Message();
System.out.println(“main Handler”);
//向子线程发送消息
threadHandler.sendMessageDelayed(message, 1000);
};
};
//创建子线程的 handler
private Handler threadHandler;

@Override
protected void onCreate(Bundle saveInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

HandlerThread thread = new HandlerThread("handlerThread");
//创建子线程的 handler
threadHandler = new Handler(thread.getLooper()) {
    public void handlerMessage(Message msg) {
        Message message = new Message();
        //向主线程发送消息
        mHandler.sendMessageDelayed(message, 1000);
    };
};

}
7. Android 中更新 UI 的几种方式

Android 中更新 UI 的 4 种方式:

runOnUiThread
handler 的 post
handler 的 sendMessage
View 自身的 post

文中大部分转载自:http://it.51xw.net/mobile/1000b7.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好名字都被猪取了-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值