【Android】HandlerThread原理分析

个人博客:
http://www.milovetingting.cn

HandlerThread是一个内部拥有Handler和Looper的特殊Thread,可以方便地在子线程中处理消息。

简单使用

HandlerThread的使用比较简单。

mHandlerThread = new HandlerThread(THREAD_NAME);
mHandlerThread.start();

首先,实例化一个HandlerThread,然后调用start()方法。在start()方法中,会调用run()方法:

@Override
public void run() {
    mTid = Process.myTid();
	//实例化looper对象
    Looper.prepare();
    synchronized (this) {
		//获取looper对象
        mLooper = Looper.myLooper();
		//通知其它线程
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
	//开启循环
    Looper.loop();
    mTid = -1;
}

然后,定义处理子线程消息的Handler:

mThreadLooper = mHandlerThread.getLooper();

mThreadHandler = new Handler(mThreadLooper, new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_THREAD_UPDATE:
                    //在子线程中执行耗时任务
                    SystemClock.sleep(3000);
                    mMainHandler.sendEmptyMessage(MSG_MAIN_UPDATE);
                    break;
                default:
                    break;
            }
            return false;
        }
    });

在HandlerThread.getLooper()方法中:

public Looper getLooper() {
    if (!isAlive()) {
        return null;
    }
    
    // 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;
}

在getLooper()方法中,由于子线程可能还没有准备好looper,因此,会调用wait()方法等待,如果子线程looper已经准备好了,则会通过notifyAll()来唤醒。

在子线程中可以执行耗时的操作,执行完成后,可以通过在UI线程的Handler发送消息去通知UI变更。

mMainHandler.sendEmptyMessage(MSG_MAIN_UPDATE);

UI线程的Handler:

static class MainHandler extends Handler {

	//为防止内存泄漏,引入WeakReference
    private WeakReference<Activity> mWeakReference;

    public MainHandler(Activity activity) {
        mWeakReference = new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        MainActivity activity = (MainActivity) mWeakReference.get();
        if (activity != null) {
            switch (msg.what) {
                case MSG_MAIN_UPDATE:
                    activity.updateInfo();
                    break;
                default:
                    break;
            }
        }

    }
}

为防止内存泄漏,引入WeakReference。在onDestory()方法中,移除所有消息:

mMainHandler.removeCallbacksAndMessages(null);

mThreadLooper.quit();

源码地址:https://github.com/milovetingting/Samples/tree/master/HandlerThread

posted @ 2019-04-03 16:18  milovetingting  阅读(128)  评论(0编辑  收藏  举报