java handler使用方法_Handler中post方法的调用流程和使用场景

本文详细解析了Java Handler的post方法的工作流程,从创建Handler、封装Runnable到MessageQueue的分发,再到最终执行run方法。通过实例说明了Handler在处理线程间通信,特别是在线程恢复如onActivityResult时避免UI线程错误的重要性。通过理解Handler的运作机制,有助于提升Android应用的多线程编程能力。

最近一直在学习多线程,handler的作用真的很重要啊,所以保存这篇看的蛮懂的。

Handler mHandler = newHandler();

mHandler.post(newRunnable() {

@Overridepublic voidrun() {

showContentView(contentView);

}

});

下面我们先来看一下这个方法是怎么执行的

首先:

public final booleanpost(Runnable r)

{return sendMessageDelayed(getPostMessage(r), 0);

}

它把Runnable重新封装了一遍然后调用了sendMessageDelayed方法

看一下是怎么封装的

private finalMessage getPostMessage(Runnable r) {

Message m=Message.obtain();

m.callback=r;returnm;

}

看到了吧,用过Handler的都知道Message是用来记录信息的最小单元,这里把Runnable封装到一个Message对象并返回

然后:

public final boolean sendMessageDelayed(Message msg, longdelayMillis)

{if (delayMillis < 0) {

delayMillis= 0;

}return sendMessageAtTime(msg, SystemClock.uptimeMillis() +delayMillis);

}

这里就是对delayMillis做了一下有效性检测

紧接着:

public boolean sendMessageAtTime(Message msg, longuptimeMillis)

{boolean sent = false;

MessageQueue queue=mQueue;if (queue != null) {

msg.target= this;

sent=queue.enqueueMessage(msg, uptimeMillis);

}else{

RuntimeException e= newRuntimeException(this + " sendMessageAtTime() called with no mQueue");

Log.w("Looper", e.getMessage(), e);

}returnsent;

}

Handler对象把Message压到了MessageQueue队列里面

貌似方法到这里就return了,那么压进去的信息是怎么发送的呢? 这得从Handler的原理说起了。有很多人已经写了这个原理了,就不在做阐述

可以查看这篇博客《android handler线程原理详详解》

然后我们去分发信息的点去看是如何执行的

public static final voidloop() {

Looper me=myLooper();

MessageQueue queue=me.mQueue;while (true) {

Message msg= queue.next(); //might block//if (!me.mRun) {//break;//}

if (msg != null) {if (msg.target == null) {//No target is a magic identifier for the quit message.

return;

}if (me.mLogging!= null) me.mLogging.println(">>>>> Dispatching to " + msg.target + " "

+ msg.callback + ": " +msg.what

);

msg.target.dispatchMessage(msg);if (me.mLogging!= null) me.mLogging.println("<<<<< Finished to " + msg.target + " "

+msg.callback);

msg.recycle();

}

}

}

Looper对象把MessageQueue里面的Message逐个取出来,注意看msg.target.dispatchMessage(msg)这一句。

Message类定义了一个字段target,这个字段就是Handler类型,存的对象就是创建这个message的对象,也就是我们的handler对象。

然后就是调用我们的handler里面的dispatchMessage(msg)方法了

public voiddispatchMessage(Message msg) {if (msg.callback != null) {

handleCallback(msg);

}else{if (mCallback != null) {if(mCallback.handleMessage(msg)) {return;

}

}

handleMessage(msg);

}

}

看到没有,一开始我们的Runnable传进来,然后调用GetPostMessage方法把Runnable赋值给了Massage里面的callback,

在分发的时候判断如果callback不是null就调用handleCallback(msg)方法。

最后,执行我们的线程。

private final voidhandleCallback(Message message) {

message.callback.run();

}

---------------------------------------------------------小小分割线----------------------------------------------------------

意义:

到了这里,我们发现貌似这玩意也就是转了一圈又调用了线程的run而已么,那么这又有什么用呢。

如果我们给handler传入的是一个message,那么最后会调用我们的handler的handleMessage(Message)方法,然后我们再去判断最后再去处理

,但是我们用runnable可以直接传入如何操作的对象,不需要再接收到消息后再去判断message的what然后选择做什么操作,从代码清晰的角度,

我也觉得这样子会比在判断一遍要清晰,容易理解很多。

---------------------------------------------------------小小分割线----------------------------------------------------------

所解决的问题:

请看博文第一段代码,这里面的runnable执行了一个setContentView(View),这里的handler是在onActivityResult里面调用的,也就是注销后重新登录回到主页面的这种情况,这个view里面包含了一些fragment,然后activity里面绑定fragment是需要是活动状态的,如果不用handler,直接执行,在onActivityResult方法执行期间activity还是在onPause状态,所以在程序执行到添加fragment的时候报错了,而用了handler就能保证这段代码最后会在activity处于活动状态既UI线程里面执行了。

原文链接:http://blog.youkuaiyun.com/panjidong_3/article/details/7890383

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值