HandlerThread源码的实现

QuibblerQuibbler 2020-04-25 约 9 分钟 1694 次阅读

HandlerThread源码的实现

HandlerThread继承自Thread,和普通线程一样,只不过HandlerThread有自己的Looper,线程启动之后可以用HandlerThread中的Looper创建Handler,向Handler发送消息,将任务放到线程中执行。比如熟悉的IntentService,内部就是借助HandlerThread在子线程中执行onHandleIntent(Intent intent)方法,参考IntentService原理和IntentService使用详解。

源码不到200行,接下来就从源码慢慢揭开HandlerThread的面纱。

package android.os;
	/**
	 * 具有Looper的Thread。,可以使用Looper创建Handler
	 * <p>
	 * 请注意,就像使用常规的Thread一样,必须仍然调用start()。
	 */
	public class HandlerThread extends Thread {
	    Looper mLooper;
            private Handler mHandler;
		...
	}

1、构造HandlerThread

HandlerThread构造函数,传入线程名和优先级。默认优先级为Process.THREAD_PRIORITY_DEFAULT。

public HandlerThread(String name) {
        super(name);
        mPriority = Process.THREAD_PRIORITY_DEFAULT;
    }
    
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }

2、启动HandlerThread

run():初始化Looper,并开启Looper循环。也就是线程调用start()之后,就可以获取子线程的 Looper,进而在其它线程(比如主线程中)用HandlerThread线程中的Looper构造Handler对象,通过这个Handler可以向HandlerThread发送消息,消息将在HandlerThread线程中被处理。

@Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

onLooperPrepared():方法为空方法,从源码注释可以看到这个方法是留给开发者自己重写实现当Looper准备好,开启循环前需要做的准备工作。

/**
     * 如果需要在Looper循环之前执行某些设置,则可以显式覆盖此回调方法。
     */
    protected void onLooperPrepared() {
    }

3、HandlerThread中的Looper

getLooper():返回当前HandlerThread线程中的Looper对象mLooper。

/**
     * 此方法返回与此线程关联的Looper。 如果此线程尚未启动,或者由于任何原因isAlive()返回false,则此方法将返回null。 
     * 如果已启动此线程,则此方法将阻塞,直到循环器已初始化。
     */
    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;
    }

getThreadHandler():返回当前线程中的Handler,该方法以及被hide,说明之后将被Google移除。

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

可以参考IntentService的做法:先获取HandlerThread的Looper,创建ThreadHandler实例(而不是通过HandlerThread获取Handler)。向这个Handler发送消息,从而在HandlerThread中执行不同的方法。

3、HandlerThread退出

quit():直接退出当前HandlerThread,内部调用Looper的quit()方法直接退出。

public boolean quit() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quit();
            return true;
        }
        return false;
    }

quitSafely():安全退出当前HandlerThread,内部调用Looper的quitSafely()方法,终止循环。

public boolean quitSafely() {
        Looper looper = getLooper();
        if (looper != null) {
            looper.quitSafely();
            return true;
        }
        return false;
    }

HandlerThread的使用方法可以参考IntentService源码。IntentService就是非常标准的利用HandlerThread将耗时操作放到子线程中,并在执行完方法后,结束Service自身。详细参考:IntentService原理。

推荐博客:

        Android HandlerThread

        Android多线程:手把手教你使用HandlerThread

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w