Android SDK源码解析篇之HandlerThread使用及源码解析
来源:     阅读:551
云上智慧
发布于 2020-04-24 17:18
查看主页

原本准备今天整理一下IntentService的源码解析,但是发现必需先总结一个HandlerThread的知识点才可以讲它,所以我今天就讲一下HandlerThread的使用及源码解析。

HandlerThread的使用

 public void startHandlerThread(){        final HandlerThread myHandlerThread = new HandlerThread("myHandlerThread");        myHandlerThread.start();        workHandler = new Handler((myHandlerThread.getLooper())){            @Override            public void handleMessage(Message message){                super.handleMessage(message);                switch (message.what){                    case 0:                        Log.d(TAG, "收到来自主线程的消息.."+Thread.currentThread().getName());                        break;                    case 1:                        Log.d(TAG, "收到来自子线程的消息.."+Thread.currentThread().getName());                        break;                }            }        };        workHandler.sendEmptyMessage(0);        new Runnable(){            @Override            public void run() {                workHandler.sendEmptyMessage(1);            }        }.run();    }

程序运行结果打印如下

02-26 20:06:34.195 30062-30101/com.txVideo.demo D/LoadingActivity: 收到来自主线程的消息..myHandlerThread02-26 20:06:34.195 30062-30101/com.txVideo.demo D/LoadingActivity: 收到来自子线程的消息..myHandlerThread

这段代码中我们创立了一个HandlerThread的实例对象myHandlerThread,并在workHandler中执行相关的操作.最终可以就看出不论是在主线程还是子线程发送消息,都是在这个myHandlerThread线程中工作。

源码分析

首先我们开始看HandlerThread.java的源码

public class HandlerThread extends Thread {    int mPriority;    int mTid = -1;    Looper mLooper;    private @Nullable Handler mHandler;    public HandlerThread(String name) {        super(name);        mPriority = Process.THREAD_PRIORITY_DEFAULT;    }    public HandlerThread(String name, int priority) {        super(name);        mPriority = priority;    }    protected void onLooperPrepared() {    }    @Override    public void run() {        mTid = Process.myTid();        Looper.prepare();        synchronized (this) {            mLooper = Looper.myLooper();            notifyAll();        }        Process.setThreadPriority(mPriority);        onLooperPrepared();        Looper.loop();        mTid = -1;    }    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;    }  @NonNull    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;    }  public int getThreadId() {        return mTid;    }}

看完源码,我们可以看出,HandlerThread其本质是Thread的子类,也就是一个子线程,里面有三个常量

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

从run方法里我们可以看出,它所做的操作就是在这个线程中调用一个Looper对象的loop方法,而后当我们开始运行这个HandlerThread实例对象时,它的Looper也就开始了循环.那如何中止它呢?

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

中止时就用到了上述的quit()方法。
那么接下来我们通过用法结合HandlerThread线程的原理,来分析一下它的运行过程。那么回到我们最开始的使用来逐行分析。

 final HandlerThread myHandlerThread = new  HandlerThread("myHandlerThread"); myHandlerThread.start();

这里我们创立了一个HandlerThread的实例对象myHandlerThread,通过调用start()方法来开启了这个线程中的Looper循环。

        workHandler = new Handler((myHandlerThread.getLooper())){            @Override            public void handleMessage(Message message){                super.handleMessage(message);                switch (message.what){                    case 0:                        Log.d(TAG, "收到来自主线程的消息.."+Thread.currentThread().getName());                        break;                    case 1:                        Log.d(TAG, "收到来自子线程的消息.."+Thread.currentThread().getName());                        break;                }            }        };

接下来我们创立了一个执行myHandlerThread的工作handler,它负责HandlerThread做实际的业务,它在创立时,通过myHandlerThread的getLooper()方法来获取Looper对象,而后利用这个Looper对象来创立了这个Handler,从上篇Handler的源码分析中我们可以得知,每一个Looper维护了自己的一个消息队列,因而当我们给这个Handler发送消息时,其实也就是给myHandlerThread线程里的Looper对象发送消息,因而我们只要要在执行业务时调用

workHandler.sendEmptyMessage(0); //主线程发送消息        new Runnable(){            @Override            public void run() {                workHandler.sendEmptyMessage(1);            }        }.run(); // 子线程里发送消息

我们可以通过打印结果看出其都是运行在myHandlerThread的线程中的,当我们使用完毕时,还需要关闭myHandlerThread中的Looper循环,也就是调用如下代码

myHandlerThread.quit()

HandlerThread的使用还是很简单的,那么接下来我们总结一下它的工作原理:

总结一下它的特点

通过全篇的分析,其实HandlerThread就是为了分担主线程中的压力,去做少量其余的操作。
今天的HandlerThread原理就总结到这里啦,觉得对您有帮助记得点个赞~

免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 系统环境 服务器应用
相关推荐
关于CSS 预解决的前台面试问题
java程序员须知增量架构方法与系统构建
承接上篇这里谈V(VW/VH/VM)单位的用场景
js基础笔记一
如何使用基于整数的手动SQL注入技术
首页
搜索
订单
购物车
我的