Android HandlerThread分析[通俗易懂]

之前Handler分析的文章有分析过,子线程Thread中是不能直接使用Handler的,需要调用Looper.prepare()方法,因此Android就为我们提供了Handler和Thread结合的方法HandlerThread方法,我们先来看下HandlerThread的源码:publicclassHandlerThreadextendsThread{intmP…

大家好,又见面了,我是你们的朋友全栈君。

之前Handler 分析的文章有分析过,子线程Thread中是不能直接使用Handler的,需要调用Looper.prepare()方法,因此Android就为我们提供了Handler和Thread结合的方法HandlerThread方法,我们先来看下HandlerThread的源码:

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;
    }

    /**
     * Constructs a HandlerThread.
     * @param name
     * @param priority The priority to run the thread at. The value supplied must be from
     * {@link android.os.Process} and not from java.lang.Thread.
     */
    public HandlerThread(String name, int priority) {
        super(name);
        mPriority = priority;
    }

    /**
     * Call back method that can be explicitly overridden if needed to execute some
     * setup before Looper loops.
     */
    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;
    }

    /**
     * This method returns the Looper associated with this thread. If this thread not been started
     * or for any reason isAlive() returns false, this method will return null. If this thread
     * has been started, this method will block until the looper has been initialized.
     * @return The looper.
     */
    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;
    }

    /**
     * @return a shared {@link Handler} associated with this thread
     * @hide
     */
    @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;
    }

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

很简单的源码HandlerThread继承Thread主要看:

@Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();//手动为子线程创建了looper
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();//开始轮询
        mTid = -1;
    }

可以看到run方法中为子线程创建了looper,并把对象放到线程中,然后通过Looper.loop();开启循环消息。

其他方法:

getThreadHandler: 获取当前线程的handler

quit:清空所有消息

quitSafely:只情况延时消息 

getLooper:获取线程中的looper对象

 

我们看下HandlerThread的使用:

private void startThread(){
    HandlerThread handlerThread = new HandlerThread("thread_one");
    handlerThread.start();
    workHandler = new Handler(handlerThread.getLooper()){//子线程handler
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            try {
                Thread.sleep(1000);//子线程中处理耗时操作
                mainHandler.sendEmptyMessage(0);//处理完后发送消息给主线程更新UI

            }catch (Exception e){

            }
        }
    };

    workHandler.sendEmptyMessage(0);

    mainHandler = new Handler(){//主线程handler
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            mBtn.setText("start");//主线程中更新UI
        }
    };
}

例子中我们看到我们通过handlerThread.getLooper()获取子线程的looper然后与workHandler,我们知道handler的线程是依赖与与之关联的looper线程,所以workHandler是子线程的handler.

然后我们new 一个未传looper的handler,默认与主线程关联,所以mainHandler是主线程的handler.

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/127757.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 对供应商锁定说不:为原生资产建立一个开放的跨链桥标准[通俗易懂]

    对供应商锁定说不:为原生资产建立一个开放的跨链桥标准[通俗易懂]我们将与大家一起建立开放的原生资产跨链桥标准,将用户、dApp开发者和区块链生态的利益放在最核心的位置。

    2022年5月25日
  • c盘扩展卷灰色无法操作的解决办法_win10c盘扩展卷是灰色的

    c盘扩展卷灰色无法操作的解决办法_win10c盘扩展卷是灰色的今天有百事网网友“丅亿页”遇到了这样一个问题:电脑C盘剩余容量太小,在看到百事网的一篇“如何合并磁盘分区windows7调整分区大小方法”文章后,也想将自己C盘系统盘空间扩大。按照上面文章中介绍的步

    2022年8月1日
  • 成功鲜有偶然:一览IT名人的教育成长经历

    成功鲜有偶然:一览IT名人的教育成长经历由于篇幅有限,只列举受公共认知度较高的创始人(百度百科对应人物词条被顶超过1000次)国内三强:李彦宏(百度创始人):本科就读于北京大学,硕士就读于布法罗纽约州立大学。曾任Infoseek工程师。马云(阿里巴巴创始人):本科就读于杭州师范学院。马化腾(腾讯创始人):本科就读于深圳大学。大三门户网站:王志东(新浪创始人):本科就读于北京大学,点击科技创始人。丁磊(网易创始人):本科就读于电子科

    2022年8月30日
  • js Date 使用详解[通俗易懂]

    js Date 使用详解[通俗易懂]jsDate使用详解varmyDate=newDate();myDate.getYear();//获取当前年份(2位)myDate.getFullYear();//获取完整的年份

    2022年7月4日
  • java多线程—Thread、Runnable和Callable区别

    多线程编程优点进程之间不能共享内存,但线程之间共享内存非常容易。系统创建线程所分配的资源相对创建进程而言,代价非常小。Java中实现多线程有3种方法:继承Thread类实现Runnable接口实现Callable接口(参考<Java编程思想(第4版)> 21.2.4章节,原来一直以为是2种,后来发现是3种)回到顶部第一种实现方法—继承Thread类继承Thread类,需要覆盖方法r…

    2022年4月7日
  • 永久短网址生成 可以永久使用的短链接推荐

    永久短网址生成 可以永久使用的短链接推荐一、使用场景微博、短信、微信在推送信息的时候都有字符的数量限制,如果分享一个长网址,很容易就超出限制,发不出去。短网址服务可以把一个长网址变成短网址,方便在社交网络上传播。二、需求微信中链接过长容易被系统屏蔽,导致推送信息他人无法看到,或者是整个信息被收起来!短信、微博中字符数超级严格一旦超过了规定的字符数。就会导致信息发送失败!综上几个现在最长的场景,很显然,要尽可能的短…

    2022年5月31日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号