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绑定在一起,构建成一个完整的消息传递系统。

  • 相关阅读:
    uva 562
    uva 624
    hdu 3826
    CF 89 div2 A
    看视屏学编程之接口、抽象类
    看视频学编程之SQL数据库基础
    看视频学编程之WinForm
    看视频学编程之骑士飞行棋—自己做(单机版)
    看视频学编程之继承
    看视频学编程之C#中的类
  • 原文地址:https://www.cnblogs.com/doubleyoujs/p/7761174.html
Copyright © 2011-2022 走看看