HandlerThread 源码解析

来源:互联网 发布:身份证恶搞制作软件 编辑:程序博客网 时间:2024/06/05 02:13

转载至: http://www.androidchina.net/2975.html

HandlerThread构造方法

/** * 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;    //当前线程id    int mTid = -1;    //当前线程持有的Looper对象    Looper mLooper;    //构造方法    public HandlerThread(String name) {        //调用父类默认的方法创建线程        super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }   //带优先级参数的构造方法    public HandlerThread(String name, int priority) {        super(name);        mPriority = priority;    }...............}

分析:该类开头就给出了一个描述:该类用于创建一个带Looper循环的线程,Looper对象用于创建Handler对象,值得注意的是在创建Handler

对象之前需要调用start()方法启动线程。这里可能有些人会有疑问?为啥需要先调用start()方法之后才能创建Handler呢?后面我们会解答。

上面的代码注释已经很清楚了,HandlerThread类有两个构造方法,不同之处就是设置当前线程的优先级参数。你可以根据自己的情况来设置优先

级,也可以使用默认优先级。

HandlerThrad的run方法

public class HandlerThread extends Thread {  /**     * Call back method that can be explicitly overridden if needed to execute some     * setup before Looper loops.     */    protected void onLooperPrepared() {    }    @Override    public void run() {        //获得当前线程的id        mTid = Process.myTid();        //准备循环条件        Looper.prepare();        //持有锁机制来获得当前线程的Looper对象        synchronized (this) {            mLooper = Looper.myLooper();            //发出通知,当前线程已经创建mLooper对象成功,这里主要是通知getLooper方法中的wait            notifyAll();        }        //设置当前线程的优先级        Process.setThreadPriority(mPriority);        //该方法实现体是空的,子类可以实现该方法,作用就是在线程循环之前做一些准备工作,当然子类也可以不实现。        onLooperPrepared();        //启动loop        Looper.loop();        mTid = -1;    }}

分析:以上代码中的注释已经写得很清楚了,以上run方法主要作用就是调用了Looper.prepare和Looper.loop构建了一个循环线程。值得一提的

是,run方法中在启动loop循环之前调用了onLooperPrepared方法,该方法的实现是一个空的,用户可以在子类中实现该方法。该方法的作用是

在线程loop之前做一些初始化工作,当然你也可以不实现该方法,具体看需求。由此也可以看出,Google工程师在编写代码时也考虑到代码的可扩展性。牛B!

getLooper获得当前线程的Looper对象

/**    * This method returns the Looper associated with this thread. If this thread not been started    * or for any reason is isAlive() returns false, this method will return null. If this thread    * has been started, this method will block until the looper has been initialized.    * @return The looper.    */   public Looper getLooper() {       //如果线程不是存活的,则直接返回null       if (!isAlive()) {           return null;       }       // If the thread has been started, wait until the looper has been created.       //如果线程已经启动,但是Looper还未创建的话,就等待,知道Looper创建成功       synchronized (this) {           while (isAlive() && mLooper == null) {               try {                   wait();               } catch (InterruptedException e) {               }           }       }       return mLooper;   }

分析:其实方法开头的英文注释已经解释的很清楚了:该方法主要作用是获得当前HandlerThread线程中的mLooper对象。

首先判断当前线程是否存活,如果不是存活的,这直接返回null。其次如果当前线程存活的,在判断线程的成员变量mLooper是否为null,如果为

null,说明当前线程已经创建成功,但是还没来得及创建Looper对象,因此,这里会调用wait方法去等待,当run方法中的notifyAll方法调用之后

通知当前线程的wait方法等待结束,跳出循环,获得mLooper对象的值。

总结:在获得mLooper对象的时候存在一个同步的问题,只有当线程创建成功并且Looper对象也创建成功之后才能获得mLooper的值。这里等待方法wait和run方法中的notifyAll方法共同完成同步问题。

quit结束当前线程的循环

public boolean quit() {        Looper looper = getLooper();        if (looper != null) {            looper.quit();            return true;        }        return false;    }//安全退出循环 public boolean quitSafely() {        Looper looper = getLooper();        if (looper != null) {            looper.quitSafely();            return true;        }        return false;    }

总结:

1.HandlerThread适用于构建循环线程。

2.在创建Handler作为HandlerThread线程消息执行者的时候必须调用start方法之后,因为创建Handler需要的Looper参数是从HandlerThread类中获得,而Looper对象的赋值又是在HandlerThread的run方法中创建。

0 0
原创粉丝点击