学习HandlerThread

HandlerThread是一个扩展了Thread的类。也就意味着它和普通的Thread类的调用没有什么区别,仍然要调用start()请添加图片描述
如上图所示,扩展后的HandlerThread类有一个Looper和Handler。
关于这一块的知识可以参考一下《关于Handler我们应该知道的知识》

HandlerThread的run方法:

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

调用了start()就是启动了一个线程,这个线程首先就创建了一个Looper。

  • Looper.prepare();是为当前线程准备好一个Looper,
  • Looper.myLooper();是取回创建好的Looper。
  • onLooperPrepared();如果运行消息队列前要设置一些东西,可以重写这个方法
  • Looper.loop();在此线程中运行消息队列

要停止已启动的Looper,必须要调用Looper的quit()方法,HandlerThread就有这么一个方法:

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

  • getLooper();拿到HandleThread实例里的Looper
  • looper.quit();结束当前线程的Looper

说了这么多,结合我上一篇文章《关于Handler我们应该知道的知识》我们知道HandlerThread提供了一种便利给在线程中创建Looper来处理我们的任务。

虽然HandlerThread类里有getThreadHandler()方法得到Handler,但是你不可能调用到它。这个方法用@hide注释了

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

@hide 它实际是控制了android.jar包的东西

我们在另一篇文章里再说@hide的东西吧。我们继续说HandlerThread。

因此我们只能自己创建一个Handler实例去绑定HandlerThread线程的Looper:

这样的我们的任务就可以放到其他的线程去执行了。来个实例吧!

 val handlerThread = HandlerThread("Hello")

        handlerThread.start() // 要在绑定Handler前调用,否则Looper就没有创建好

        val handler = object: Handler(handlerThread.looper) {
            override fun handleMessage(msg: Message) {
                println("Hello world8888888888888888888")
            }
        }

        handler.sendMessage(Message.obtain())

        handler.sendMessage(Message.obtain())

        Thread.sleep(3000)
        handlerThread.quit()// 不再使用的话,要记得停到Looper
        // 收到error java.lang.IllegalStateException: Handler ... 
        // sending message to a Handler on a dead thread
        handler.sendMessage(Message.obtain()) 

比如我们自己创建一个线程,并让它启动一个Looper来帮我们做事:

var mLooper: Looper? = null
// 启动一个线程,并为当前线程
Thread{
    Looper.prepare()
    synchronized(this) {
        mLooper = Looper.myLooper()
    }
    Looper.loop()
}.start()

Thread.sleep(3000) // Looper创建是要些时间的,所以我们等一下它。

val myHandler = object: Handler(mLooper!!){
     override fun handleMessage(msg: Message) {
        println("Hey world @@@@@@@@@")
     }
 }

myHandler.sendMessage(Message.obtain())

优雅一点的版本,java的会更简单些:

 var mLooper: Looper? = null
        val lock = ReentrantLock()
        val condition = lock.newCondition()
        Thread{
            Looper.prepare()
            try {
                lock.lock()
                mLooper = Looper.myLooper()
                condition.signalAll()
            }catch (e: Exception){

            }finally {
                lock.unlock()
            }

            Looper.loop()
        }.start()

        try {
            lock.lock()
            if (mLooper == null) condition.await()
        }catch (e: Exception){
            e.printStackTrace()
        }finally {
            lock.unlock()
        }

        val myHandler = object: Handler(mLooper!!){
            override fun handleMessage(msg: Message) {
                println("Hey world @@@@@@@@@")
            }
        }

        myHandler.sendMessage(Message.obtain())

就这么多,谢谢捧场!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值