zoukankan      html  css  js  c++  java
  • HandlerThread学习

    之前已经了解Handler的一些知识,今天主要研究Google封装的实现线程通信的一个类HandlerThread。

    一、HandlerThread使用

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ......
            HandlerThread handlerThread = new HandlerThread("handler-thread");
            handlerThread.start();
    
            mHandler = new Handler(handlerThread.getLooper()){
                @Override
                public void handleMessage(Message msg) {
                    //这里已经不是在主线程,而是在HandlerThread线程中了
                    super.handleMessage(msg);
                }
            };
            //主线程向子线程发送消息
            mHandler.sendEmptyMessage(100);
        }
    1. new一个HandlerThread并启动
    2. 实例化Handler并获取HandlerThread的Looper
    3. 可以在任何地方使用handler发送消息,handler里面实现是异步的

    HandlerThread简单的替代了之前研究过的一段代码,如下:

        Thread mThread = new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                mHandler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        ......
                        super.handleMessage(msg);
                    }
                };
                Looper.loop();
            }
        });

    这样替代后我们不用自己去实现Thread,来执行耗时操作。

    HandlerThread本身是一个Thread,在里面做了一个消息循环的管道,Handler往里面扔消息,并得到消息进行处理。

    对比上面两个mHandler,我们可以发现其构造方法不一样,一个没有传Looper,通过Handler源码可以发现是使用当前线程的Looper,一个有,用的就是HandlerThread的Looper。

        public Handler(Looper looper, Callback callback, boolean async) {
            mLooper = looper;
            mQueue = looper.mQueue;
            mCallback = callback;
            mAsynchronous = async;
        }

    上述只是Handler其中一个构造方法,传Looper的类会最终走到这个构造方法中,有两个参数需要注意1、mLooper 2、mQueue

    Handler在构建的时候就拿到Looper和MessageQueue,传输消息机制就是很容易理解了。

    没有传Looper的构造方法只是把mLooper = looper 换成了mLooper = Looper.myLooper()。

    二、源码分析 

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

    以上代码是HandlerThread主要的代码,我们可以看见run方法中构建了Looper的消息循环,并没有Handler,可以说HandlerThread就是一个加了消息循环的Thread,在这里看起来和Handler并没有什么关系。

    我们在使用的时候才会把Handler和HandlerThread的Looper绑定在一起,构建成一个完整的消息传递系统。

  • 相关阅读:
    SCI写作经典替换词,瞬间高大上!(转)
    最佳化常用测试函数 Optimization Test functions
    算法复杂度速查表
    VS 代码行统计
    CPLEX IDE 菜单栏语言设置( 中文 英文 韩文 等多国语言 设置)
    如何从PDF文件中提取矢量图
    Matlab无法打开M文件的错误( Undefined function or method 'uiopen' for input arguments of type 'char)
    visual studio 资源视图 空白 解决方案
    MFC DialogBar 按钮灰色不响应
    嗨翻C语言笔记(二)
  • 原文地址:https://www.cnblogs.com/doubleyoujs/p/7761174.html
Copyright © 2011-2022 走看看