android耗时任务_handler

本文深入探讨了Android中的Handler机制,包括Handler、Message、MessageQueue和Looper四个核心角色。Handler负责发送和处理Message,Message作为信息载体,MessageQueue按照FIFO规则存储Message,Looper在特定线程中执行消息循环。文中通过一个简单的实例说明了如何启动Looper循环,以及如何通过Handler在UI线程和非UI线程间协调耗时任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

handler机制的5个角色

在上一篇android处理耗时任务_ANR中简单的介绍了一个handler的用法,现在我们来看看他的基本原理。

Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

Message:消息,携带要传送的信息和任务,是handler机制的载体。

MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

Looper和MessageQueue一一对应,创建一个Looper的同时会创建一个MessageQueue。而Handler与它们的关系,只是简单的聚集关系,即Handler里会引用当前线程里的特定Looper和MessageQueue。这样说来,多个Handler都可以共享同一Looper和MessageQueue了。当然,这些Handler也就运行在同一个线程里。本人专门画了下面的图,我想这个图已经能够简洁明了的说明他们的关系了。


一个简单的实例

class LooperThread extends Thread {
       public Handler mHandler;
       public void run() {
           Looper.prepare();
	   //Handler不带参数的默认构造函数:new Handler(),实际上是通过Looper.myLooper()来获取当前线程中的消息循环
           mHandler = new Handler() {
           public void handleMessage(Message msg) {
                  // process incoming messages here
           }
           };
           Looper.loop();
       }
}

默认情况下一个线程是不存在消息循环Looper的,需要调用Looper.prepare()来给线程创建一个Looper,同时会创建一个MessageQueue,调用Looper.loop()来使消息循环起作用,从消息队列里取消息,处理消息。Looper.loop()其实就是开启了一个死循环,不停的从MessageQueue中抽取Message并分配。所以写在Looper.loop()之后的代码不会被立即执行,当调用后mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。

值得一提的是,Android中很多的线程间的通信都和Handler有关:
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)

上面三个其实都和handler.post(Runnable)有关。

Activity.runOnUiThread(Runnable)

如果当前线程是UI线程,那么该Runnable会立即执行,如果当前的线程不是UI线程则调用UI线程handler的post()方法将其放入UI线程的消息队列中。

View.post(Runnable)
View.post(Runnable)方法。在post(Runnable action)方法里,View获得当前线程(即UI线程)的Handler,然后将action对象post到Handler里。在Handler里,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler再次处理该Message时,有一条分支(未解释的那条)就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值