看了handler源码后,对其用法及原理的一点分析

来源:互联网 发布:mac打开csgo黑屏 编辑:程序博客网 时间:2024/04/30 06:10

Looper维持了一个消息队列,下面是looper源代码中loop函数,实现looper中消息队列的循环。

 public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;


        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            msg.target.dispatchMessage(msg);



            msg.recycle();
        }
    }

那么Message具体是什么呢?

打开源码一看,居然这么简单,其实就包含了一些数据,有几个obtain函数用于构造message对象

<span style="font-family:SimSun;"> int flags; long when;     Bundle data;     Handler target;          Runnable callback;   </span>
那么有了looper消息队列,有了message,貌似以及可以完成所有需要的功能了,那么handler是个什么鬼。 有没有想过,即使有了message,looper队列,可以不断地加取message,但是去了message总得用的吧,handler就是做这么个事,,实现往消息队列里加消息,取消息,并作出处理。 Handler mHandler = new Handler(); mHandler.postDelayed(new Runnable() { @Override public void run() { //。。。。 } }, 2000); 其中的runnble就是个interface,定义了一个函数——run Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { } };这是处理message的回调。 那么handler对callback的处理是什么顺序呢?

public void dispatchMessage(Message msg) {

//如果Message本身有callback,则直接交给Message的callback处理

if(msg.callback != null) {

handleCallback(msg);

}else {

//如果本Handler设置了mCallback,则交给mCallback处理

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

//最后才是交给子类处理

handleMessage(msg);

}

}

Message如果自带了callback处理,则交给callback处理。

Handler如果设置了全局的mCallback,则交给mCallback处理。

如果上述都没有,该消息则会被交给Handler子类实现的handleMessage来处理


下面是我自己编的一段代码,在不同线程上进行操作,用handlerThread类实现同步

HandlerThread ht = new HandlerThread("mythread");
ht.start();
Looper looper = ht.getLooper();
Handler myhandler = new Handler(looper);
Runnable myrun = new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("second Thread"+Thread.currentThread().getId());
}
};
Message myMessage = new Message();
myMessage = Message.obtain(myhandler, myrun);
myhandler.sendMessage(myMessage);

0 0
原创粉丝点击