Handler和HandlerThread简单研究

一.   HandlerLooperMessageQueen间的关系

Looper:每个线程只有一个Looper,它负责管理MessageQueen,会不断的从MessageQueen中取出消息,并将消息分给对应的Handler处理。

MessageQueen:由Looper负责管理,它采用先进先出的方式管理Message

Handler:它把消息发送给由Looper管理的MessageQueen,并负责处理Looper给它的消息

 

二.   Handler用法

1.      调用obtainMessage方法获取Message对象就能避免创建对象,从而减少内存的开销

2.      Handler中obtainMessage与new Message的区别:

obtainmessage()是从消息池中拿来一个msg 不需要另开辟空间。

new Message()需要重新申请,效率低,obtianmessage()可以循环利用;

第一种写法是message 从handler 类获取,从而可以直接向该handler对象发送消息,第二种写法是直接调用 handler 的发送消息方法发送消息。

3.      post(Runnable r)和sendMessage(Message msg)区别:

1). 一个Handler只有一个队列;

2). 在调用Handler.post(Runnable runnable)方法时,会将runnable封装成一个Message;

3). 在队列执行时,会判断当前的Message里是否封装了Runnable,如果封闭了,就直接执行Runnable,如果没有,将当前的Message传递给handleMessage(Message msg)处理;

源代码如下:

    public final boolean sendMessage(Messagemsg){

        return sendMessageDelayed(msg, 0);

    }

    public final boolean post(Runnable r){

       return sendMessageDelayed(getPostMessage(r), 0);

}

private final Message getPostMessage(Runnable r) {

   Message m =Message.obtain();

   m.callback = r;

   return m;

}

区别是:在调用Handler.post(Runnable runnable)方法时,会将runnable封装成一个Message;

4.      Handler在实例化的时候可以设置一个callback<Handler.Callback>,callback也有一个handleMessage(Messagemsg)方法,测试结果如下:

    class MyCallback implementsandroid.os.Handler.Callback{

        @Override

        public boolean handleMessage(Messagemsg) {

            Log.d("FF","MyCallback--->handleMessage");

            return true;// return false;-----------------------------------------------------位置1

        }

    }

   

    private Handler mCallbackHandler = new Handler(new MyCallback()){

        @Override

        public void handleMessage(Message msg){

            super.handleMessage(msg);

            Log.d("FF","mCallbackHandler--->handleMessage");-------------------位置2

        }

    };

    private void buttonClick2(){

        mCallbackHandler.sendEmptyMessage(0);

    }

测试结果:

位置1:callbackhandleMessage(Message msg)

位置2:自身的handleMessage(Message msg)

若位置1是return false时,位置2会被调用

若位置1是return true时,位置2则不会被调用

 

 

三.   HandlerThread用法

1.      继承于Thread,所以HandlerThread本质就是一个线程

2. HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息

3.

(1)为什么要使用HandlerThread

在我们的应用程序当中为了实现同时完成多个任务,所以我们会在应用程序当中创建多个线程。为了让多个线程之间能够方便的通信,我们会使用Handler实现线程间的通信。

(2)如何在线程当中实例化Handler

在线程中实例化Handler我们需要保证线程当中包含Looper(注意UI-Thread默认包含Looper)

为线程创建Looper的方法如下:在线程run()方法当中先调用Looper.prepare()初始化Looper,然后再run()方法最后调用Looper.loop(),这样我们就在该线程当中创建好Looper(注意Looper.loop()方法默认是死循环)

(3) HandlerThread就是实现Looper更加简单的方法。官网描述如下:

Handy class forstarting a new thread that has a looper. The looper can then be used to createhandler classes. Note that start() must still be called.

 

尽管HandlerThread的文档比较简单,但是它的使用并没有想象的那么easy

1.   创建一个HandlerThread,即创建了一个包含Looper的线程。

HandlerThreadhandlerThread = new HandlerThread("leochin.com");

handlerThread.start();//创建HandlerThread后一定要记得start()

2.   获取HandlerThreadLooper

Looper looper =handlerThread.getLooper();

3.    创建Handler,通过Looper初始化

Handler handler =new Handler(looper);

通过以上三步我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。

如果想让HandlerThread退出,则需要调用handlerThread.quit()

 

HandlerThread源代码如下:

    public void run() {

        mTid = Process.myTid();

        Looper.prepare();

        synchronized (this) {

            mLooper = Looper.myLooper();

            Process.setThreadPriority(mPriority);

            notifyAll();

        }

        onLooperPrepared();

        Looper.loop();

        mTid = -1;

    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值