美文网首页
九、IdleHandler与HandlerThread

九、IdleHandler与HandlerThread

作者: Serenity那年 | 来源:发表于2018-10-28 21:27 被阅读2次
  • 1、IdleHandler是MessageQueue里面的一个内部接口,在MessageQueue的next()方法(next()方法用来从MessageQueue中取Message)中调用;
    public static interface IdleHandler {
        /**
         * Called when the message queue has run out of messages and will now
         * wait for more.  Return true to keep your idle handler active, false
         * to have it removed.  This may be called if there are still messages
         * pending in the queue, but they are all scheduled to be dispatched
         * after the current time.
         */
        boolean queueIdle();
    }

queueIdle()方法在MessageQueue中没有消息时,才会回调;
返回值为false时,只会在循环取消息时,第一次没有消息时回调;
返回值为true时,每次在循环去消息时,没有消息时都会回调此方法;

  • 2、HandlerThread继承于Thread,只不过HandlerThread在启动start后,会在内部主动创建这个线程持有的Looper,并且开启Looper.loop();
    //HandlerThread中的run方法
    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

因此可以获取通过handlerThread.getLooper()获取looper,来创建一个子线程的Handler;


具体的使用实例:

package com.zcbl.airport_assist.permissiondemo;

import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.util.Log;

import java.lang.reflect.Field;

/**
 * Created by serenitynanian on 2018/10/18.
 * 这个类主要用来演示HandlerThread和IdelHandler的用法
 * HandlerThread实现了子线程通知主线程的功能
 */

public class HandlerThreadAndIdlelHandler implements MessageQueue.IdleHandler {

    private static final String TAG = "HandlerThreadAndIdlelHandler";
    private final Handler handler;
    private MessageQueue queue;

    private ChangeListener listener ;

    public void setListener(ChangeListener listener) {
        this.listener = listener;
    }

    public interface ChangeListener{
        void onChange();
    }
    public HandlerThreadAndIdlelHandler() {


        //参数为指定线程名字
        HandlerThread handlerThread = new HandlerThread("handlerThread");
        handlerThread.start();
        Looper looper = handlerThread.getLooper();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            //MessageQueue ,只能在6.0以上才能使用此方法获取MessageQueue
            queue = looper.getQueue();
        }else{
            //6.0以下通过反射获取MessageQueue
            Class<Looper> looperClass = Looper.class;
            Field mQueue = null;
            try {
                mQueue = looperClass.getDeclaredField("mQueue");
                mQueue.setAccessible(true);
                queue = (MessageQueue) mQueue.get(looper);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        //注册idleHandler
        queue.addIdleHandler(this);


        //通过子线程的Looper创建一个子线程的Handler
        handler = new Handler(looper){
            @Override
            public void handleMessage(Message msg) {
                //因为是子线程的Looper,这个handlerMessage运行在子线程中
                Log.i(TAG, "同步数据.....");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };



    }

    /**
     * idleHandler接口的方法
     * @return
     * 返回true  进入闲置就会回调此方法
     * 返回false 进入闲置只会回调一次此方法
     */
    @Override
    public boolean queueIdle() {
        //等待所有的消息都分发出去后,messageQueue进入闲置状态,才会回调此方法
        if (null != listener) {
            listener.onChange();
        }

        return true;
    }


    /**
     * 释放idleHandler
     */
    public void releaseIdleHandler(){

        if (null != queue) {
            queue.removeIdleHandler(this);
        }

    }

    /**
     * 外界调用此方法 使用子线程中的handler发送消息
     * 
     * 外界可以连续调用此方法,让子线程中的handler处理耗时操作,等所有消息链表中的消息分发完成后,
     * 才会回调IdleHandler中的queueIdle方法;这样就能实现一个子线程连续执行几个耗时任务,等所有的任务都执行了,
     * 才通知外界,所有的任务都执行完毕;
     */
    public void async(){
        handler.sendEmptyMessage(0);
    }
}

具体的调用:

 HandlerThreadAndIdlelHandler handlerThreadAndIdlelHandler = new HandlerThreadAndIdlelHandler();
    Handler handler = new Handler();

    private void userHandlerThreadAndIdleThread() {
        handlerThreadAndIdlelHandler.setListener(new HandlerThreadAndIdlelHandler.ChangeListener() {
            @Override
            public void onChange() {
                //这个是在子线程中
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.i(TAG, "接收子线程中发送过来的消息,更新UI");
                    }
                });
            }
        });
    }

    //持续点击几次,也就是执行多任务
    public void click(View view) {
        handlerThreadAndIdlelHandler.async();
    }

相关文章

网友评论

      本文标题:九、IdleHandler与HandlerThread

      本文链接:https://www.haomeiwen.com/subject/qoujzftx.html