java的handler机制_Handler运行机制

本文介绍了Android中Handler的机制,包括如何发送和分发消息,以及如何处理线程间的数据传递。Handler主要用于在子线程和主线程之间同步,更新UI。它使用Message对象在MessageQueue中排队,由Looper线程不断循环处理。当尝试在未准备Looper的线程中创建Handler时,会出现错误。解决方法是在自定义线程中初始化Looper。
摘要由CSDN通过智能技术生成

首先。这些都是从网上跟自己的总结,涉及文章不止一篇 也不是全抄 如有错误 请留言 多谢。

主要接受子线程发送的数据, 并用此数据配合主线程更新UI.因为Android 是线程不安全的。

关键词

android.os.Handler 、 android.os.Handler.Callback

Looper、

Threadle、Runnable

Message、Message queue

1.Handler sendMessage 与 obtainMessage ().sendToTarget()

Message本身带有属性

Message msg = new Message()

msg.what = xxx;//标识

msg.arg1  = xxx;//可选,用于传轻量级Integer对象。

msg.arg2  = xxx;//可选,用于传轻量级Integer对象。

msg.obj   = xxx;//任意对象

msg还有个可以设置Bundle的方法:msg.setData(b);Bundle b = msg.getData();

对于Bundle可以设置多个值在多次传递后一次取出的性能优化。可见Bundle也很强大。

handler.sendMessage(msg);

这样能做到我们的需求。

obtainMessage 用于获取连接池中的对象Message并把标识与任意对象传给Handler所在的线程,

sendToTarget 底层实现sendMessage方法,这样做可以减少Message创建时的性能开销。

2. Handler中分发消息的一些方法

post(Runnable)

postAtTime(Runnable,long)

postDelayed(Runnable long)

sendEmptyMessage(int)

sendMessage(Message)

sendMessageAtTime(Message,long)

sendMessageDelayed(Message,long)

以上post方法允许你排列一个Runnable对象到主线程队列中,因此它并不是新开一个线程。

sendMessage方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

3.Handler.callback接口实现handlerMessage()用来分发线程的任务。主线程可以直接继承该接口然后实现handlerMessage而不是实现handler重写handlerMessage()。

4.Handler的实现原理

Handler.sendMessage()后。会把Message对象放入一个MessageQueue队列,该队列属于某个Looper对象,每个Looper对象通过ThreadLocal.set(new Looper())跟一个Thread绑定了,Looper对象所属的线程在Looper.Loop方法中循环执行从MessageQueue队列读取Message对象,

并把Message对象交由Handler处理,调用Handler的dispatchMessage方法。

publicvoiddispatchMessage(Message msg) {

if(msg.callback !=null) {

handleCallback(msg);

} else{

if(mCallback !=null) {

if(mCallback.handleMessage(msg)) {//handleMessage-1

return;

}

}

handleMessage(msg);//handleMessage-2

}

}

privatefinalvoidhandleCallback(Message message) {

message.callback.run();//callback为RUNNABLE

}

也就是说 当我们在创建Handler的时候,并sendMessage的时候Handler必须已经存在了。

而我们在post的时候。操作是在runnable里的handleCallback,代码如上。

5.非主线程产生Can't create handler inside thread that has not called Looper.prepare()

这是因为在主线程已经有 Looper.prepareMainLooper();和Looper.loop();对操作进行处理了。

Looper.prepareMainLooper:新建了一个looper对象,并与当前进程进行了绑定

Looper.loop:线程建立消息循环机制,循环从MessageQueue获取Message对象,调用

msg.target.dispatchMessage(msg);进行处理msg.target在myThreadHandler.sendEmptyMessage(0)

设置进去的,因为一个Thead中可以建立多个Hander,通过msg.target保证MessageQueue中的每个msg 交由发送message的handler进行处理,而在Handler创建的时候会自动获取当前线程的Looper(只有主线程ActivityThread创建才有,我们创建的线程没有),如果不存在则报错。

解决:

可在我们创建的线程里创建Looper.(Looper.perpare())

Looper.myLooper().loop();//建立一个消息循环,该线程不会退出

8fee4877175d1a35bed010b551e4004b.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值