Android HandlerThread use and source code analysis

HandlerThread, as the name suggests, in essence, it is a joint collaboration with Handler mission Thread.

First, source code analysis

HandlerThread implementation process is very simple, there is a total of more than a hundred lines of code, the entire class is the core process Looper.prepare () to create a message queue and turn on the news cycle by Looper.loop () method in the run through, this is what we Looper Handler connection media. We first look at its internal implementation:

/**
 * 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 Handler mHandler;

    /**
     * 构造函数,设置线程名称,优先级默认
     */
    public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }

    /**
     * 构造函数,设置线程名称和优先级
     */
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }

    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();  //创建Looper对象 & 消息队列
        synchronized (this) { //通过锁机制获取当前线程的Looper对象
            mLooper = Looper.myLooper();
            notifyAll(); //通知getLooper方法looper已经创建成功,对应getLooper方法中的wait()
        }
        Process.setThreadPriority(mPriority); //设置线程优先级
        onLooperPrepared();  //重写此方法,作用是在消息循环之前进行一些准备工作
        Looper.loop();  //开启消息循环
        mTid = -1;
    }

    /**
     * 消息循环前的准备工作,根据需求决定是否重写
     */
    protected void onLooperPrepared() {
    }

    /**
     * 使用同步锁机制获取当前线程Looper。这是为了保证只有当线程创建成功并且其
     * 对应的Looper对象也创建成功后才能获得Looper的值,然后才能将创建的Handler
     * 与工作线程的Looper对象绑定,从而将任务切换到Looper绑定工作线程中执行
     */
    public Looper getLooper() {
        if (!isAlive()) {  //线程还未开启,返回null
            return null;
        }

        // 使用对象锁机制:如果线程已开启, 进入等待状态直到looper成功初始化.
        synchronized (this) {
            while (isAlive() && mLooper == null) {
                try {
                    wait();  //等待Looper初始化完成,对应run方法中的notifyAll
                } catch (InterruptedException e) {
                }
            }
        }
        return mLooper;
    }

    /**
     * @return a shared {@link Handler} associated with this thread
     * @hide
     */
    public Handler getThreadHandler() {
        if (mHandler == null) {
            mHandler = new Handler(getLooper());
        }
        return mHandler;
    }

    /**
     * 直接退出线程的消息循环(强行退出循环)
     */
    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;
    }

    /**
     * Returns the identifier of this thread. See Process.myTid().
     */
    public int getThreadId() {
        return mTid;
    }
}

Comment has been very clear, will not be repeated explain the meaning of each method.

Summary: HandlerThread create Looper and message queues within the thread, and the thread open message loop after the start. We can use this construct Looper thread Handler object such binding work, and then send the message to a message queue by Handler, so that the message can be removed and HandlerThread perform specific background task based on the message type. Because HandlerThread run method is an infinite loop, so when we no longer use HandlerThread should call it quit or quitSafely method to terminate a thread, so you can save system resources.

Second, the use

Now that we know works HandlerThread, and then we look at the use HandlerThread steps:

private HandlerThread handlerThread; //工作线程

private Handler handler; //通知线程执行消息

//1. 创建HandlerThread实例
handlerThread = new HandlerThread("HT");
//2. 启动工作线程(启动消息循环系统)
handlerThread.start();
//3. 使用工作线程的Looper创建Handler,切换到工作线程处理后台任务
handler = new Handler(handlerThread.getLooper()) {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        try {
            Thread.sleep(2000); //模拟耗时任务
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        int anInt = new Random().nextInt(1000);
        LogUtils.d("更新UI:" + anInt);
    }
};

//4. 发送消息通知handlerThread执行耗时任务
handler.sendEmptyMessage(0);

//5. 任务完成后停止线程释放资源
handlerThread.quit();

These are the steps HandlerThread of use, it is a typical usage scenario in Android is IntentService, interested can click on the following link to see what kind of role the actor HandlerThread in IntentService.

Android IntentService use and source code analysis


reference

"Android development of artistic exploration."

Reproduced in: https: //www.jianshu.com/p/c041567e4dfc

Guess you like

Origin blog.csdn.net/weixin_34375251/article/details/91136129