学习HandlerThread
创始人
2024-05-25 07:42:03

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

HandlerThread的run方法:

    @Overridepublic 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*/@NonNullpublic 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 threadhandler.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? = nullval 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())

就这么多,谢谢捧场!

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...