现在的位置: 首页 > 综合 > 正文

HandlerThread

2018年05月24日 ⁄ 综合 ⁄ 共 2697字 ⁄ 字号 评论关闭

 

HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,它有个Looper成员变量。这个Looper其实就是对消息队列以及队列处理逻辑的封装,简单说就是 消息队列+消息循环。

当我们需要一个工作者线程,而不是把它当作一次性消耗品,用过即废弃的话,就可以使用它。

    private Handler mHandler = null;

    private HandlerThread mHandlerThread = null;

    private void sentRunnableToWorker(Runnable run){

        if (null == mHandlerThread)
        {
            mHandlerThread = new HandlerThread("WorkerThread");

            // 给工作者线程低优先级 
            mHandlerThread.setPriority(Thread.MIN_PRIORITY);
            mHandlerThread.start();
        }

        if (null == mHandler)
            mHandler = new Handler(mHandlerThread.getLooper());

        mHandler.post(run);

    }

AsyncQueryHandler就是基于HandlerThread封装了线程间双向通信,而HandlerThread只做了一半。

 

 

源码分析:

 

  1. public class HandlerThread extends Thread{
  2.           //线程的优先级
  3.            private int mPriority;
  4.           //线程的id
  5.            private int mTid=-1;
  6.            private Looper mLooper;
  7.            public HandlerThread(String name){
  8.                       super(name);
  9.                      //设置优先级为默认线程
  10.                      mPriority=Process.THREAD_PRIORITY_DEFAULT;
  11.            }
  12.            public HandlerThread(String name,int priority){
  13.                       super(name);
  14.                      mPriority=priority;
  15.            }
  16.           //这个如果有需要的话可以继承重写,例如可以在里面声明个Handler 关联此线程。
  17.            protected void onLooperPrepared(){}
  18.            //这个很熟悉吧
  19.            public void run(){
  20.                //得到当前线程的id
  21.                 mTid=Process.myTid;
  22.                //一旦调用这句代码,就在此线程中创建了Looper 对象。这就是为什么我们要在调用线程的start()方法后
  23.                //才能得到Looper 对象即 当 调用Looper.myLooper()时不为Null。
  24.                 Looper.prepare();
  25.                 //同步代码块,意思就是当获得mLooper对象后,唤醒所有线程。(会在以后的例子中有所体现)
  26.                synchronized(this){
  27.                      mLooper=Looper.myLooper();
  28.                      notifyAll();
  29.                }
  30.               //设置线程的优先级
  31.                Process.setThreadPriority(mPriority);
  32.              //调用上面的方法(需要用户重写)
  33.               onLooperPrepared();
  34.                //建立了消息循环
  35.                 Looper.loop();
  36.                mTid=-1;
  37.            }
  38.            public Looper getLooper(){
  39.                     //线程死了,那就只有NULL了。
  40.                      if(!isAlive()){
  41.                         return null;
  42.                     }
  43.             //看见没,又是同步代码块,正好和上面的形成对应,就是说只要线程活着并且我的looper为NULL,那么我就让你一直等。。。
  44.                    synchronized(this){
  45.                           while(isAlive()&&mLooper==null){
  46.                                try{
  47.                                          wait();
  48.                                    }catch(InterruptedException e){}
  49.                           }
  50.                    }
  51.                              return mLooper;
  52.            }
  53.           public boolean quit(){
  54.               Looper looper =getLooper();
  55.                if(looper!=null){
  56.                   //退出消息循环
  57.                    looper.quit();
  58.                    return true;
  59.               }
  60.               return false;
  61.        }
  62.          //返回线程ID
  63.          public int getThreadId(){
  64.                return mTid;
  65.         }
  66. }

复制代码

整体来说代码还是比较浅显易懂的。主要的作用是建立了一个线程,并且创立了消息队列,有来自己的looper,可以让我们在自己的线程中分发和处理消息。具体的使用示例,我会在下一帖中体现。还有要说明的是handler 与谁相关联不是看声明在什么地方,是看与哪个线程的looper挂钩。默认是主线程的looper.因为主线程中默认就有了looper,消息循环队列。

抱歉!评论已关闭.