thread和handler区别,handler thread,Thread、Handler和HandlerThread关系详解

thread和handler区别,handler thread,Thread、Handler和HandlerThread关系详解

本文主要介绍了关于线程、处理程序和HandlerThread之间关系的详细解释的相关信息。有需要的朋友可以参考一下。

前言

前几天看到一个面试问题:Thread,Handler和HandlerThread有什么区别?这个话题有意思。对于很多人来说,可能对Thread和Handler比较熟悉,它主要涉及Android的消息机制(Handler、Message、Looper、MessageQueue)。详情见《从Handler.post(Runnable r)再一次梳理Android的消息机制(以及handler的内存泄露)》。

但是这个手柄线程是用来做什么的呢?是处理程序还是线程?我们知道Handler是用来异步更新UI的,更确切地说,是用来在线程之间进行通信的。更新UI时,是子线程和UI主线程之间的通信。现在,如果我们想要在子线程之间进行通信,我们应该做什么?最后当然也是用HandlerThread完成的(不推荐,需要自己操作Looper)。Google官方很好心的帮我们打包了一个类,就是我们刚才说的:Handler Thread。(类似的封装包括针对多线程场景的AsyncTask)

使用方法

我们先来看看HandlerThread的用法:

首先,创建一个新的HandlerThread并执行start()

私有句柄mHandlerThread

.

mHandlerThread=new handler thread(' handler thread ');

handler thread . start();

创建处理程序并使用mHandlerThread.getLooper()生成Looper:

最终处理程序handler=新处理程序(mHandlerThread.getLooper()){

@覆盖

公共void handleMessage(Message msg) {

System.out.println('已接收消息');

}

};

然后创建一个新的子线程来发送消息:

新线程(新Runnable() {

@覆盖

公共无效运行(){

尝试{

thread . sleep(1000);//模拟耗时的操作

handler . senemptymessage(0);

} catch (InterruptedException e) {

e . printstacktrace();

}

}

}).start();

最后,不要忘记在灾难时释放它,以避免内存泄漏:

@覆盖

受保护的void onDestroy() {

super . on destroy();

mhandlerthread . quit();

}

结果非常简单,即在控制台上打印字符串:message received。

原理

在整个使用过程中我们完全不用关心Handler相关的事情,我们只需要发送消息,处理消息,把Looper相关的事情留给它自己。我们来看看源代码是如何实现的,先看构造方法:

公共类处理程序线程扩展线程{}

HandlerThread其实就是一个线程。和普通螺纹有什么不同?

公共类处理程序线程扩展线程{

int mPriority

int mTid=-1;

Looper mLooper

公共句柄线程(字符串名称){

超级(名);

mPriority=过程。线程优先级默认值;

}

.

}

答案是多了一个Looper,是子线程独有的,用来取消息和处理消息。继续看HandlerThread这个线程的运行方法:

受保护的void onLooperPrepared() {

}

@覆盖

公共无效运行(){

mTid=process . mytid();

looper . prepare();

同步(这){

m looper=looper . my looper();//生成活套

notify all();

}

process . setthreadpriority(m priority);

onLooperPrepared();//空方法,在创建Looper后调用。你可以自己重写逻辑。

looper . loop();//无限循环,不断从MessageQueue中取出消息,交给Handler处理。

mTid=-1;

}

主要做一些Looper操作,如果我们自己用Handler线程来实现,也要做这个操作。让我们来看看getLooper()方法:

公共Looper getLooper() {

如果(!isAlive()) {

返回null

}

//如果线程已经启动,等待直到创建了looper。

同步(这){

while (isAlive() mLooper==null) {

尝试{

wait();

} catch (InterruptedException e) {

}

}

}

返回mLooper

}

方法很简单,就是加一个同步锁。如果已经创建(isAlive()返回true)但mLooper为空,则继续等待,直到mLooper创建成功。最后看戒法。值得一提的有两条:

public boolean quit() {

looper looper=get looper();

如果(looper!=null) {

looper . quit();

返回true

}

返回false

}

public boolean quitSafely() {

looper looper=get looper();

如果(looper!=null) {

looper . quit safely();

返回true

}

返回false

}

QuitSafely指的是消息队列中仍然有消息或者延迟的消息没有被处理的情况。调用此方法后,它将被停止。

总结

HandlerThread的使用相对简单,但是我们需要明白一点:如果一个线程要处理消息,它必须有自己的Looper,无论在哪里创建Handler,它都可以处理消息。

如果不使用HandlerThread,需要手动调用Looper.prepare()和Looper.loop()方法。

以上是Thread、Handler和HandlerThread的数据整理,后续我们会继续补充相关数据。感谢您对本站的支持!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: