handler,handler是什么,handler实现机制,在android的handler机制引进的意图面试

[Android]Handler的消息机制
最经面试中,技术面试中有一个是Handler的消息机制,细细想想,我经常用到的Handler无非是在主线程(或者说Activity)新建一个Handler对象,另外一个Thread是异步加载数据,同时当他加载完数据后就send到主线程中的那个Handler对象,接着Handler来处理,刚才发送的一些消息。
& & & & &&
&1 public class HandlerTestActivity extends Activity {
&2 & & private TextV
&3 & & private static final int UPDATE = 0;
&4 & & private Handler handler = new Handler() {
&6 & & & & @Override
&7 & & & & public void handleMessage(Message msg) {
&8 & & & & & & // TODO 接收消息并且去更新UI线程上的控件内容
&9 & & & & & & if (msg.what == UPDATE) {
10 & & & & & & & & // Bundle b = msg.getData();
11 & & & & & & & & // tv.setText(b.getString(&num&));
12 & & & & & & & & tv.setText(String.valueOf(msg.obj));
13 & & & & & & }
14 & & & & & & super.handleMessage(msg);
15 & & & & }
18 & & /** Called when the activity is first created. */
19 & & @Override
20 & & public void onCreate(Bundle savedInstanceState) {
21 & & & & super.onCreate(savedInstanceState);
22 & & & & setContentView(R.layout.main);
23 & & & & tv = (TextView) findViewById(R.id.tv);
25 & & & & new Thread() {
26 & & & & & & @Override
27 & & & & & & public void run() {
28 & & & & & & & & // TODO 子线程中通过handler发送消息给handler接收,由handler去更新TextView的值
29 & & & & & & & & try {
30 & & & & & & & & & & for (int i = 0; i & 100; i++) {
31 & & & & & & & & & & & & Thread.sleep(500);
32 & & & & & & & & & & & & Message msg = new Message();
33 & & & & & & & & & & & & msg.what = UPDATE;
34 & & & & & & & & & & & & // Bundle b = new Bundle();
35 & & & & & & & & & & & & // b.putString(&num&, &更新后的值:& + i);
36 & & & & & & & & & & & & // msg.setData(b);
37 & & & & & & & & & & & & msg.obj = &更新后的值:& +
38 & & & & & & & & & & & & handler.sendMessage(msg);
39 & & & & & & & & & & }
40 & & & & & & & & } catch (InterruptedException e) {
41 & & & & & & & & & & e.printStackTrace();
42 & & & & & & & & }
43 & & & & & & }
44 & & & & }.start();
如图所示,每个Thread都一个Looper,这个Looper类是用于管理其中的消息队列(MessageQueue)的,那Handler是干嘛的呢,他是用来传递消息队列的。
那下面就分析Looper、Hanlder方法吧。
Looper方法是用来处理消息队列的,注意了,它和线程是绑定的。
要是想在子线程中获取一个Looper该怎么做呢:
& & Looper.prepare();
& & Looper looper = Looper.myLooper();
那么这些都干了哪些工作呢???
来看下它的吧:
//准备Looper相关事宜
& &public static void prepare() {
& & &//只能有一个对象哦
& & & & if (sThreadLocal.get() != null) {
& & & & & & throw new RuntimeException(&Only one Looper may be created per thread&);
& & & & &sThreadLocal.set(new Looper());
& &//构造函数
& /*新建一个消息队列
& &* 把当前运行的线程作为运行线程
& & private Looper() {
& & & & mQueue = new MessageQueue();
& & & & mRun =
& & & & mThread = Thread.currentThread();
& & & & & & &public static final Looper myLooper() {
& & & & & & & & & & & & & & //这个方法是从当前线程的ThreadLocal中拿出设置的looper
& & & & & & & & &return (Looper)sThreadLocal.get();
& & & & & & &}
& & &* Run the message queue in this thread. Be sure to call
& & &* {@link #quit()} to end the loop.
& & public static void loop() {
& & & & Looper me = myLooper();
& & & & if (me == null) {
& & & & & & throw new RuntimeException(&No L Looper.prepare() wasn't called on this thread.&);
& & & & MessageQueue queue = me.mQ
& & & & // Make sure the identity of this thread is that of the local process,
& & & & // and keep track of what that identity token actually is.
& & & & Binder.clearCallingIdentity();
& & & & final long ident = Binder.clearCallingIdentity();
& & & & while (true) {
& & & & & & Message msg = queue.next(); // might block
& & & & & & if (msg != null) {
& & & & & & & & if (msg.target == null) {
& & & & & & & & & & // No target is a magic identifier for the quit message.
& & & & & & & & & &
& & & & & & & & }
& & & & & & & & long wallStart = 0;
& & & & & & & & long threadStart = 0;
& & & & & & & & // This must be in a local variable, in case a UI event sets the logger
& & & & & & & & Printer logging = me.mL
& & & & & & & & if (logging != null) {
& & & & & & & & & & logging.println(&&&&&& Dispatching to & + msg.target + & & +
& & & & & & & & & & & & & & msg.callback + &: & + msg.what);
& & & & & & & & & & wallStart = SystemClock.currentTimeMicro();
& & & & & & & & & & threadStart = SystemClock.currentThreadTimeMicro();
& & & & & & & & }
& & & & & & & & msg.target.dispatchMessage(msg);
& & & & & & & & if (logging != null) {
& & & & & & & & & & long wallTime = SystemClock.currentTimeMicro() - wallS
& & & & & & & & & & long threadTime = SystemClock.currentThreadTimeMicro() - threadS
& & & & & & & & & & logging.println(&&&&&& Finished to & + msg.target + & & + msg.callback);
& & & & & & & & & & if (logging instanceof Profiler) {
& & & & & & & & & & & & ((Profiler) logging).profile(msg, wallStart, wallTime,
& & & & & & & & & & & & & & & & threadStart, threadTime);
& & & & & & & & & & }
& & & & & & & & }
& & & & & & & & // Make sure that during the course of dispatching the
& & & & & & & & // identity of the thread wasn't corrupted.
& & & & & & & & final long newIdent = Binder.clearCallingIdentity();
& & & & & & & & if (ident != newIdent) {
& & & & & & & & & & Log.wtf(TAG, &Thread identity changed from 0x&
& & & & & & & & & & & & & & + Long.toHexString(ident) + & to 0x&
& & & & & & & & & & & & & & + Long.toHexString(newIdent) + & while dispatching to &
& & & & & & & & & & & & & & + msg.target.getClass().getName() + & &
& & & & & & & & & & & & & & + msg.callback + & what=& + msg.what);
& & & & & & & & }
& & & & & & & &&
& & & & & & & & msg.recycle();
& & & & & & }
下面就来看下Handler:
public Handler() {
& & & & if (FIND_POTENTIAL_LEAKS) {
& & & & & & final Class&? extends Handler& klass = getClass();
& & & & & & if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
& & & & & & & & & & (klass.getModifiers() & Modifier.STATIC) == 0) {
& & & & & & & & Log.w(TAG, &The following Handler class should be static or leaks might occur: & +
& & & & & & & & & & klass.getCanonicalName());
& & & & & & }
& & & //先获得一个Looper对象,这个要是在子线程里,是需要先prepare()的
& & & & mLooper = Looper.myLooper();
& & & & if (mLooper == null) {
& & & & & & throw new RuntimeException(
& & & & & & & & &Can't create handler inside thread that has not called Looper.prepare()&);
& & & & mQueue = mLooper.mQ
& & & & mCallback =
& & &* Returns a new {@link android.os.Message Message} from the global message pool. More efficient than
& & &* creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this).
& & &* &If you don't want that facility, just call Message.obtain() instead.
& &会从消息池里面取得消息队列
& & public final Message obtainMessage()
& & & & return Message.obtain(this);
那我现在写个小例子,是在子线程实现的消息的传递。
& & public void onClick(View v) {
& & & & int id = v.getId();
& & & & if (id == R.id.btn1) {
& & & & & & new Thread() {
& & & & & & & & public void run() {
& & & & & & & & & & Log.i(&log&, &run&);
& & & & & & & & & & Looper.prepare();
& & & & & & & & & & // Looper looper = Looper.myLooper();
& & & & & & & & & & Toast.makeText(MainActivity.this, &toast&, 1).show();
& & & & & & & & & & Handler h = new Handler() {
& & & & & & & & & & & & @Override
& & & & & & & & & & & & public void handleMessage(Message msg) {
& & & & & & & & & & & & & & // TODO Auto-generated method stub
& & & & & & & & & & & & & & super.handleMessage(msg);
& & & & & & & & & & & & & & if (msg != null) {
& & & & & & & & & & & & & & & & String strMsg = (String) msg.
& & & & & & & & & & & & & & & & System.out.println(strMsg);
& & & & & & & & & & & & & & }
& & & & & & & & & & & & }
& & & & & & & & & & };
& & & & & & & & & & //获取到Handler对象的消息
& & & & & & & & & & Message msg = h.obtainMessage();
& & & & & & & & & & msg.obj = &add&;
& & & & & & & & & & msg.sendToTarget();
& & & & & & & & & & Looper.loop();// 进入loop中的循环,查看消息队列
& & & & & & & & };
& & & & & & }.start();
不知你是否理解,这个小Demo中,我们需要注意:
1 &子线程也是可以有Handler的,其实Handler只是从当前的线程中获取到Looper来监听和操作MessageQueue的。
2 子线程需要先prepare()才能获取到Looper的,是因为在子线程只是一个普通的线程,其ThreadLoacl中没有设置过Looper,所以会抛出异常,而在Looper的prepare()方法中sThreadLocal.set(new Looper())是设置了Looper的。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'weizhulin 的BLOG
用户名:weizhulin
文章数:65
评论数:224
访问量:1753907
注册日期:
阅读量:3416
阅读量:286491
阅读量:1011803
阅读量:156470
51CTO推荐博文
大家好我们这一节讲的是Android
Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title.
首先我们看一下习惯了Java编程的人,在不知道Handler的用法之前是怎么样写的程序,代码如下所示:
package&com.android.&&import&java.util.T&&import&java.util.TimerT&&import&android.app.A&&import&android.os.B&&public&class&HandlerDemo&extends&Activity&{&&&&&&&&&&&&&&&&&&private&int&title&=&0;&&&&&&&&&&&&public&void&onCreate(Bundle&savedInstanceState)&{&&&&&&&&&&super.onCreate(savedInstanceState);&&&&&&&&&&setContentView(R.layout.main);&&&&&&&&&&&&&&&&&&&&Timer&timer&=&new&Timer();&&&&&&&&&&timer.scheduleAtFixedRate(new&MyTask(),&1,&5000);&&&&&&}&&&&&&&&&&&&&&&&private&class&MyTask&extends&TimerTask{&&&&&&&&&&@Override&&&&&&&&&&public&void&run()&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&setTitle("Welcome&to&Mr&Wei's&blog&"&+&title);&&&&&&&&&&&&&&title&++;&&&&&&&&&&}&&&&&&&&&}&&}&&package
com.android.
import java.util.T
import java.util.TimerT
import android.app.A
import android.os.B
public class HandlerDemo extends Activity {
//title为setTitle方法提供变量,这里为了方便我设置成了int型
private int title = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTask(), 1, 5000);
private class MyTask extends TimerTask{
public void run() {
setTitle("Welcome to Mr Wei's blog " + title);
然而当我们执行程序,并不能达到我们预期的效果,所以Android 引进了Handler
这个特殊的类,可以说它是Runnable和Activity交互的桥梁
,所以我们只要在run方法中发送Message,而在Handler里,通过不同的Message执行不同的任务。
所以我们修改后的代码如下:
package&com.android.&&import&java.util.T&&import&java.util.TimerT&&import&android.app.A&&import&android.os.B&&import&android.os.H&&import&android.os.M&&public&class&HandlerDemo&extends&Activity&{&&&&&&&&&&&&&&&&&&private&int&title&=&0;&&&&&&&&&&&&private&Handler&mHandler&=&new&Handler(){&&&&&&&&&&&&&&&&&&&&public&void&handleMessage(Message&msg)&{&&&&&&&&&&&&&&switch&(msg.what)&{&&&&&&&&&&&&&&case&1:&&&&&&&&&&&&&&&&&&updateTitle();&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&}&&&&&&&&&&};&&&&&&};&&&&&&public&void&onCreate(Bundle&savedInstanceState)&{&&&&&&&&&&super.onCreate(savedInstanceState);&&&&&&&&&&setContentView(R.layout.main);&&&&&&&&&&&&&&&&&&&&Timer&timer&=&new&Timer();&&&&&&&&&&timer.scheduleAtFixedRate(new&MyTask(),&1,&5000);&&&&&&}&&&&&&&&&&&&&&&&private&class&MyTask&extends&TimerTask{&&&&&&&&&&@Override&&&&&&&&&&public&void&run()&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&Message&message&=&new&Message();&&&&&&&&&&&&&&message.what&=&1;&&&&&&&&&&&&&&mHandler.sendMessage(message);&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&}&&&&&&&&&&&&&&&&&&public&void&updateTitle(){&&&&&&&&&&&&&&&&&&&&setTitle("Welcome&to&Mr&Wei's&blog&"&+&title);&&&&&&&&&&title&++;&&&&&&}&&}&&package
com.android.
import java.util.T
import java.util.TimerT
import android.app.A
import android.os.B
import android.os.H
import android.os.M
public class HandlerDemo extends Activity {
//title为setTitle方法提供变量,这里为了方便我设置成了int型
private int title = 0;
private Handler mHandler = new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
updateTitle();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new MyTask(), 1, 5000);
private class MyTask extends TimerTask{
public void run() {
Message message = new Message();
message.what = 1;
mHandler.sendMessage(message);
public void updateTitle(){
setTitle("Welcome to Mr Wei's blog " + title);
下面我们看一下效果图:
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)'
src="http://hi.csdn.net/attachment//0_S75.gif" alt="" />
650) this.width=650;" onclick='window.open("/viewpic.php?refimg=" + this.src)'
src="http://hi.csdn.net/attachment//0_cqN.gif" alt="" />本文出自 “” 博客,请务必保留此出处
了这篇文章
类别:┆阅读(0)┆评论(0)
本文收录至博客专题:《》《》
13:21:59 13:28:54 16:14:43 09:28:58 16:09:45 21:06:42 15:19:19 10:46:27 09:50:01 09:51:12 21:41:09 15:40:33 11:08:59详解Android中Handler的内部实现原理
作者:孙群
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了Android中Handler的内部实现原理,对Handler和消息循环的实现原理进行源码分析,需要的朋友可以参考下
本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解。
概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制。我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功能。但作为程序员,我不能只知道怎么用Handler,还要知道其内部如何实现的。Handler的内部实现主要涉及到如下几个类: Thread、MessageQueue和Looper。这几类之间的关系可以用如下的图来简单说明:
Thread是最基础的,Looper和MessageQueue都构建在Thread之上,Handler又构建在Looper和MessageQueue之上,我们通过Handler间接地与下面这几个相对底层一点的类打交道。
一图胜千言
我们在本文讨论了Thread、MessageQueue、Looper以及Hanlder的之间的关系,我们可以通过如下一张传送带的图来更形象的理解他们之间的关系。
在现实生活的生产生活中,存在着各种各样的传送带,传送带上面洒满了各种货物,传送带在发动机滚轮的带动下一直在向前滚动,不断有新的货物放置在传送带的一端,货物在传送带的带动下送到另一端进行收集处理。
我们可以把传送带上的货物看做是一个个的Message,而承载这些货物的传送带就是装载Message的消息队列MessageQueue。传送带是靠发送机滚轮带动起来转动的,我们可以把发送机滚轮看做是Looper,而发动机的转动是需要电源的,我们可以把电源看做是线程Thread,所有的消息循环的一切操作都是基于某个线程的。一切准备就绪,我们只需要按下电源开关发动机就会转动起来,这个开关就是Looper的loop方法,当我们按下开关的时候,我们就相当于执行了Looper的loop方法,此时Looper就会驱动着消息队列循环起来。
那Hanlder在传送带模型中相当于什么呢?我们可以将Handler看做是放入货物以及取走货物的管道:货物从一端顺着管道划入传送带,货物又从另一端顺着管道划出传送带。我们在传送带的一端放入货物的操作就相当于我们调用了Handler的sendMessageXXX、sendEmptyMessageXXX或postXXX方法,这就把Message对象放入到了消息队列MessageQueue中了。当货物从传送带的另一端顺着管道划出时,我们就相当于调用了Hanlder的dispatchMessage方法,在该方法中我们完成对Message的处理。
下面重点介绍Handler:
Handler是暴露给开发者最顶层的一个类,其构建在Thread、Looper与MessageQueue之上。
Handler具有多个构造函数,签名分别如下所示:
1. publicHandler()
2. publicHandler(Callbackcallback)
3. publicHandler(Looperlooper)
4. publicHandler(Looperlooper, Callbackcallback)
第1个和第2个构造函数都没有传递Looper,这两个构造函数都将通过调用Looper.myLooper()获取当前线程绑定的Looper对象,然后将该Looper对象保存到名为mLooper的成员字段中。
第3个和第4个构造函数传递了Looper对象,这两个构造函数会将该Looper保存到名为mLooper的成员字段中。
第2个和第4个构造函数还传递了Callback对象,Callback是Handler中的内部接口,需要实现其内部的handleMessage方法,Callback代码如下:
public interface Callback {
public boolean handleMessage(Message msg);
Handler.Callback是用来处理Message的一种手段,如果没有传递该参数,那么就应该重写Handler的handleMessage方法,也就是说为了使得Handler能够处理Message,我们有两种办法:
1. 向Hanlder的构造函数传入一个Handler.Callback对象,并实现Handler.Callback的handleMessage方法
2. 无需向Hanlder的构造函数传入Handler.Callback对象,但是需要重写Handler本身的handleMessage方法
也就是说无论哪种方式,我们都得通过某种方式实现handleMessage方法,这点与Java中对Thread的设计有异曲同工之处。
在Java中,如果我们想使用多线程,有两种办法:
1. 向Thread的构造函数传入一个Runnable对象,并实现Runnable的run方法
2. 无需向Thread的构造函数传入Runnable对象,但是要重写Thread本身的run方法
所以只要用过多线程Thread,应该就对Hanlder这种需要实现handleMessage的两种方式了然于心了。
我们知道通过sendMessageXXX系列方法可以向消息队列中添加消息,我们通过源码可以看出这些方法的调用顺序,
sendMessage调用了sendMessageDelayed,sendMessageDelayed又调用了sendMessageAtTime。
Handler中还有一系列的sendEmptyMessageXXX方法,而这些sendEmptyMessageXXX方法在其内部又分别调用了其对应的sendMessageXXX方法。
通过以下调用关系图我们可以看的更清楚些:
由此可见所有的sendMessageXXX方法和sendEmptyMessageXXX最终都调用了sendMessageAtTime方法。
我们再来看看postXXX方法,会发现postXXX方法在其内部又调用了对应的sendMessageXXX方法,我们可以查看下sendMessage的源码:
public final boolean post(Runnable r)
return sendMessageDelayed(getPostMessage(r), 0);
可以看到内部调用了getPostMessage方法,该方法传入一个Runnable对象,得到一个Message对象,getPostMessage的源码如下:
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback =
通过上面的代码我们可以看到在getPostMessage方法中,我们创建了一个Message对象,并将传入的Runnable对象赋值给Message的callback成员字段,然后返回该Message,然后在post方法中该携带有Runnable信息的Message传入到sendMessageDelayed方法中。由此我们可以看到所有的postXXX方法内部都需要借助sendMessageXXX方法来实现,所以postXXX与sendMessageXXX并不是对立关系,而是postXXX依赖sendMessageXXX,所以postXXX方法可以通过sendMessageXXX方法向消息队列中传入消息,只不过通过postXXX方法向消息队列中传入的消息都携带有Runnable对象(Message.callback)。
我们可以通过如下关系图看清楚postXXX系列方法与sendMessageXXX方法之间的调用关系:
通过分别分析sendEmptyMessageXXX、postXXX方法与sendMessageXXX方法之间的关系,我们可以看到在Handler中所有可以直接或间接向消息队列发送Message的方法最终都调用了sendMessageAtTime方法,该方法的源码如下:
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQ
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
//注意下面这行代码
return enqueueMessage(queue, msg, uptimeMillis);
该方法内部调用了enqueueMessage方法,该方法的源码如下:
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//注意下面这行代码
msg.target =
if (mAsynchronous) {
msg.setAsynchronous(true);
//注意下面这行代码
return queue.enqueueMessage(msg, uptimeMillis);
在该方法中有两件事需要注意:
1. msg.target = this
该代码将Message的target绑定为当前的Handler
2. queue.enqueueMessage
变量queue表示的是Handler所绑定的消息队列MessageQueue,通过调用queue.enqueueMessage(msg, uptimeMillis)我们将Message放入到消息队列中。
所以我们通过下图可以看到完整的方法调用顺序:
我们在分析Looper.loop()的源码时发现,Looper一直在不断的从消息队列中通过MessageQueue的next方法获取Message,然后通过代码msg.target.dispatchMessage(msg)让该msg所绑定的Handler(Message.target)执行dispatchMessage方法以实现对Message的处理。
Handler的dispatchMessage的源码如下:
public void dispatchMessage(Message msg) {
//注意下面这行代码
if (msg.callback != null) {
handleCallback(msg);
//注意下面这行代码
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
//注意下面这行代码
handleMessage(msg);
我们来分析下这段代码:
1.首先会判断msg.callback存不存在,msg.callback是Runnable类型,如果msg.callback存在,那么说明该Message是通过执行Handler的postXXX系列方法将Message放入到消息队列中的,这种情况下会执行handleCallback(msg), handleCallback源码如下:
private static void handleCallback(Message message) {
message.callback.run();
这样我们我们就清楚地看到我们执行了msg.callback的run方法,也就是执行了postXXX所传递的Runnable对象的run方法。
2.如果我们不是通过postXXX系列方法将Message放入到消息队列中的,那么msg.callback就是null,代码继续往下执行,接着我们会判断Handler的成员字段mCallback存不存在。mCallback是Hanlder.Callback类型的,我们在上面提到过,在Handler的构造函数中我们可以传递Hanlder.Callback类型的对象,该对象需要实现handleMessage方法,如果我们在构造函数中传递了该Callback对象,那么我们就会让Callback的handleMessage方法来处理Message。
3.如果我们在构造函数中没有传入Callback类型的对象,那么mCallback就为null,那么我们会调用Handler自身的hanldeMessage方法,该方法默认是个空方法,我们需要自己是重写实现该方法。
综上,我们可以看到Handler提供了三种途径处理Message,而且处理有前后优先级之分:首先尝试让postXXX中传递的Runnable执行,其次尝试让Handler构造函数中传入的Callback的handleMessage方法处理,最后才是让Handler自身的handleMessage方法处理Message。
希望本文对于大家理解Android中的Handler和消息循环机制有所帮助。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具

我要回帖

更多关于 android的handler机制 的文章

 

随机推荐