美文网首页
HandlerThread源码分析

HandlerThread源码分析

作者: BelieveFrank | 来源:发表于2019-08-18 23:38 被阅读0次

    HandlerThread本质上还是Thread,继承了Thread。它与Thread的区别是内部维护了一个Looper。当我们在子线程中使用Handler的时候需要创建一个Looper

    public void run() {
        super.run();
        Looper.prepare();
        Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                //...
            }
        };
        Looper.loop();
    }
    

    这样写需要我们自己创建一个Looper,当有了HandlerThread的时候我们就不必这个做了,采用HandlerThread的代码如下

    HandlerThread handlerThread = new HandlerThread("thread name");
    handlerThread.start();
    mHandler = new Handler(handlerThread.getLooper())
    

    HandlerThead的源码比较简单,这里就直接贴出来了

    /**
     * Handy class for starting a new thread that has a looper. The looper can then be
     * used to create handler classes. Note that start() must still be called.
     *  
     */
    public class HandlerThread extends Thread {
       int mPriority;
       int mTid = -1;
       Looper mLooper;
       private @Nullable Handler mHandler;
       // name是线程名
       public HandlerThread(String name) {
           super(name);
           mPriority = Process.THREAD_PRIORITY_DEFAULT;
       }
        // priority是线程优先级
       public HandlerThread(String name, int priority) {
           super(name);
           mPriority = priority;
       }
        // 当Looper 准备好的时候调用
       protected void onLooperPrepared() {
       }
        //代码的核心,创建Looper,并调用loop开启消息队列的循环
       @Override
       public void run() {
           mTid = Process.myTid();
           Looper.prepare();
           synchronized (this) {
               mLooper = Looper.myLooper();
               notifyAll();//如果有调用getLooper的去通知Looper已经准备好了,可以返回给调用者了。
           }
           Process.setThreadPriority(mPriority);
           onLooperPrepared();
           Looper.loop();
           mTid = -1;
       }
        // 获得线程的Looper
       public Looper getLooper() {
           if (!isAlive()) {
               return null;
           }
           // 如果线程开启了,会一直等到Looper创建完成,再返回创建的Looper
           // If the thread has been started, wait until the looper has been created.
           synchronized (this) {
               while (isAlive() && mLooper == null) {
                   try {
                       wait();
                   } catch (InterruptedException e) {
                   }
               }
           }
           return mLooper;
       }
        // 获得与该Looper关联的Handler,隐藏方法
       @NonNull
       public Handler getThreadHandler() {
           if (mHandler == null) {
               mHandler = new Handler(getLooper());
            }
            return mHandler;
        }
        // 退出线程的Looper
        public boolean quit() {
            Looper looper = getLooper();
            if (looper != null) {
                looper.quit();
                return true;
            }
            return false;
        }
        // 安全的退出线程的Looper
        public boolean quitSafely() {
            Looper looper = getLooper();
            if (looper != null) {
                looper.quitSafely();
                return true;
            }
            return false;
        }
        //获得线程id,通过Process.myTid()获得的
        public int getThreadId() {
            return mTid;
        }
    }
    

    quit和quieSafely的区别

    quit方法把MessageQueue消息池中所有的消息全部清空。quitSafely方法只会清空MessageQueue消息池中所有的延迟消息(延迟消息是指通过sendMessageDelayed或postDelayed等方法发送的消息),非延迟消息则不清除继续派发出去让Handler去处理

    相关文章

      网友评论

          本文标题:HandlerThread源码分析

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