HandlerThread

来源:互联网 发布:linux显示文件大小命令 编辑:程序博客网 时间:2024/06/15 16:18

   我们来看一下HandlerThread的源码:

/** * 一个方便的线程Thread类,HandlerThread提前为我们准备了一个Looper. * 这个looper可以用来构建一个handler类 * 注意HandlerThread的实质还是一个普通的Thread类,start()方法必须被调用 */public class HandlerThread extends Thread {    int mPriority;           //该线程被运行的优先级    int mTid = -1;          // 线程Tid    Looper mLooper;    public HandlerThread(String name) {        super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }    /**     * Constructs a HandlerThread.     * @param name     * @param priority 运行线程的优先级别。该值必须来自android.os.Process而不是java.lang.Thread      */    public HandlerThread(String name, int priority) {        super(name);        mPriority = priority;    }    /**     * 如果需要在Looper执行loop()方法前执行一些初始化操作,可以覆写该回调方法,该方法默认为空     */    protected void onLooperPrepared() {    }    /**     * 如果该HandlerThread在初始化的时候穿进去一个Runnable对象参数,     * 那么这个Runnable对象的run方法会被调用,     * 否则如果执行HandlerThread的run方法不会做任何事情和有返回值     **/    @Override    public void run() {        mTid = Process.myTid();        Looper.prepare();           //我们知道在Android中,除了主线程即UI线程默认为我们初始化了一个Looper外                                    //其余线程如果想配合Handler使用达到子线程间通信、异步等操作外                                    //必须手动调用Looper.prepare()  Looper.myLooper()    Looper.loop()                                    //等方法,而这些操作HandlerThread都帮我们做好了        synchronized (this) {            mLooper = Looper.myLooper();            notifyAll();        }        Process.setThreadPriority(mPriority);        onLooperPrepared();        Looper.loop();        mTid = -1;    }    /**     * 该方法返回了与这个Thread相关联的Looper。如果该Thread的start()方法还没有被执行或者由于某种原因导致它的     * isAlive()方法返回false值,该方法会返回null值;如果该线程已经被启动,该方法会阻塞直到looper初始化完毕     * @return The looper.     */    public Looper getLooper() {        if (!isAlive()) {            return null;        }        // 如果该线程已经被启动,该方法会阻塞直到looper初始化完毕        synchronized (this) {            while (isAlive() && mLooper == null) {                try {                    wait();                } catch (InterruptedException e) {                }            }        }        return mLooper;    }    /**     * 退出handler 线程的looper循环,不再处理接受任何Message     *      * 会导致handler线程的looper对象不再继续处理消息队列Message Queue中更多的消息对象,直接终止     *      * 在调用该方法后,任何尝试post 消息的行为都会失败     * 例如, Handler#sendMessage(Message)} 方法会返回false。     *      * 注意:     * 使用该方法可能是不安全的。因为一些消息Message对象在looper终止前还没有来得及被分派。     * 考虑使用quitSafely()方法,以确保所有待完成的工作均有秩序地完成。     *      * 返回true 如果looper对象已经被ask to 退出     * 返回false如果这个thread还没启动运行     *     * @see #quitSafely     */    public boolean quit() {        Looper looper = getLooper();        if (looper != null) {            looper.quit();            return true;        }        return false;    }/**     * 安全地退出handler线程的looper消息处理循环。     *      * 会导致handler线程的looper对象不再继续处理消息队列Message Queue中更多的消息对象,直接终止     *      * 在调用该方法后,任何尝试post 消息的行为都会失败     * 例如, Handler#sendMessage(Message)} 方法会返回false。      *     * 返回true 如果looper对象已经被ask to 退出     * 返回false如果这个thread还没启动运行     */    public boolean quitSafely() {        Looper looper = getLooper();        if (looper != null) {            looper.quitSafely();            return true;        }        return false;    }    /**     * 返回该线程的标记ID。 详情查看 Process.myTid()方法.     */    public int getThreadId() {        return mTid;    }}

  HandlerThread的一般用途

    HandlerThread handlerThread=new HandlerThread("线程A");   //创建一个线程A    handlerThread.start();                                   //启动这个线程    Handler handler=new Handler(handlerThread.getLooper()){ //在这个线程中创建一个handler对象              @Override            public void handleMessage(Message msg) {                super.handleMessage(msg);                //由于与这个handler相关联的用于Messsage循环处理的Looper是来自线程A的                //也就是说该handler是与线程A绑定的                //所以handleMessage()方法是运行在 A线程中的 ,可以执行耗时操作                .....一些耗时操作            }    };//然后我们在其它线程給Handler发送消息,如://以下代码使用了Lambda表达式   new Thread(()->         handler.sendEmptyMessage(2) //线程A负责处理该消息       ).start();

参考:Android HandlerThread 总结使用


原创粉丝点击