iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android中Handler、Thread、HandlerThread三者的区别
  • 527
分享到

Android中Handler、Thread、HandlerThread三者的区别

2024-04-02 19:04:59 527人浏览 八月长安
摘要

目录一、前期知识储备二、三者的区别三、HandlerThread的使用一、前期知识储备 (1)Handler类,上官方文档,Handler public class Handler.

一、前期知识储备

(1)Handler类,上官方文档,Handler

public class Handler.A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be perfORMed on a different thread than your own.

(2)Thread类,上官方文档,Thread

public class Thread. extends Object implements Runnable.A thread is a thread of execution in a program. The Java Virtual Machine allows an application to have multiple threads of execution running concurrently.

Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.

(3)HandlerThread类,上官方文档,HandlerThread

public class HandlerThread. extends Thread. Handy class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.

二、三者的区别

①Handler:在Android中负责发送和处理消息,通过它可以实现其他支线线程与主线程之间的消息通讯。

②Thread:Java进程中执行运算的最小单位,亦即执行处理机调度的基本单位。某一进程中一路单独运行的程序。

③HandlerThread:一个继承自Thread的类HandlerThread,Android中没有对Java中的Thread进行任何封装,而是提供了一个继承自Thread的类HandlerThread类,这个类对Java的Thread做了很多便利的封装。

———————————————————我是分割线—————————————————————

其实这个问题,最主要的关注点还是落在了HandlerThread类上,那么这个类到底有什么作用,所谓的便利封装又体现在哪里?

观察HandlerThread的官方文档的两句:①Thread. Handy class for starting a new thread that has a looper.②The looper can then be used to create handler classes.

释义:HandlerThread对象start后可以获得其Looper对象,并且使用这个Looper对象实例Handler,之后Handler就可以运行在其他线程中了

———————————————————我是分割线—————————————————————

那么Handler和Looper到底是什么关系,为什么HandlerThread要做这样的处理?观看下图:

                      

Andriod提供了 Handler  和  Looper  来满足线程间的通信。 Handler 先进先出原则。 Looper 类用来管理特定线程内对象之间的消息交换 (MessageExchange) 。 

1)Looper:  一个线程可以产生一个 Looper 对象,由它来管理此线程里的 MessageQueue( 消息队列 ) 和对消息进行循环。 

2)Handler:  你可以构造 Handler 对象来与 Looper 沟通,以便 push 新消息到 MessageQueue 里 ; 或者接收 Looper 从 Message Queue 取出 所送来的消息。 

3) Message Queue( 消息队列 ): 用来存放线程放入的消息。 

4) Message:是线程间通讯的消息载体。两个码头之间运输货物,Message充当集装箱的功能,里面可以存放任何你想传递的消息。

看到这里就明白了为什么:如果一个线程要处理消息,那么它必须拥有自己的Looper,并不是Handler在哪里创建,就可以在哪里处理消息。

注:对应关系Thread(1):Looper(1):MessageQueen(1):Handler(n).

三、HandlerThread的使用

正如前面所说,线程间通信的时候,比如Android中常见的更新UI,涉及到的是子线程和主线程之间的通信,实现方式就是Handler+Looper,但是要自己手动操作Looper,不推荐,所以谷歌封装了HandlerThread类(类似于AsyncTask类)。

上代码,具体实现:


public class MainActivity extends AppCompatActivity {
 
    Handler mainHandler,workHandler;
    HandlerThread mHandlerThread;
    TextView text;
    Button button1,button2;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.text1);
 
        // 创建与主线程关联的Handler
        mainHandler = new Handler();
        
        mHandlerThread = new HandlerThread("handlerThread");
 
        
        mHandlerThread.start();
 
        
 
        workHandler = new Handler(mHandlerThread.getLooper()){
            @Override
            public void handleMessage(Message msg)
            {
                //设置了两种消息处理操作,通过msg来进行识别
                switch(msg.what){
                    case 1:
                        try {
                            //延时操作
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        // 通过主线程Handler.post方法进行在主线程的UI更新操作
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run () {
                                text.setText("第一次执行");
                            }
                        });
                        break;
                    case 2:
                        try {
                            Thread.sleep(3000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run () {
                                text.setText("第二次执行");
                            }
                        });
                        break;
                    default:
                        break;
                }
            }
        };
 
        
        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message msg = Message.obtain();
                msg.what = 1; //消息的标识
                msg.obj = "A"; // 消息的存放
                // 通过Handler发送消息到其绑定的消息队列
                workHandler.sendMessage(msg);
            }
        });
 
        button2 = (Button) findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message msg = Message.obtain();
                msg.what = 2; 
                msg.obj = "B"; 
                workHandler.sendMessage(msg);
            }
        });
 
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandlerThread.quit(); // 退出消息循环
        workHandler.removeCallbacks(null); // 防止Handler内存泄露 清空消息队列
    }
}

从上面代码可以看出,HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,然后在内部直接实现了Looper的实现,这是Handler消息机制必不可少的。有了自己的looper,可以让我们在自己的线程中分发和处理消息。如果不用HandlerThread的话,需要手动去调用Looper.prepare()Looper.loop()这些方法。


// 子线程中创建新的Handler 没有使用HandlerThread
new Thread () {
    @Override
    public void run() {
        Looper.prepare();
        Hnadler handler = new Handler();
        Looper.loop();
    } 
}

提供一些其他Android消息机制分析,帮助理解读者理解:

①Handler是Android消息机制的上层接口,通过它可以轻松地将一个任务切换到Handler所在的线程中去执行,该线程既可以是主线程,也可以是子线程,要看构造Handler时使用的构造方法中传入的Looper位于哪里;

②Handler的运行需要底层的MessageQueue和Looper的支撑,Handler创建的时候会采用当前线程的Looper来构造消息循环系统,而线程默认是没有Looper的,如果需要使用Handler就必须为线程创建Looper;

③上述代码中的第一个Handler-mainHandler,实例化的时候,直接在onCreate()方法中new出了实例,其实是其已经在主线程中了,主线程-ActivityThread,ActivityThread被创建时就会初始化Looper,这就是主线程中默认可以直接使用Handler的原因;

④上述代码中的第二个Handler-workHandler,它在实例化的时候,参数传入了 mHandlerThread.getLooper() ,注意,这个Handler使用的就不是主线程的Looper了,而是子线程的Looper,HandlerThread在调用start()方法之后,就可以获取到子线程的Looper,然后将其传入workHandler的构造方法中,那么此时的workHandler就会运行在子线程中,用于处理耗时操作。

⑤Handler的工作原理:Handler创建时会采用当前线程的Looper来构建内部消息循环系统,如果当前线程没有Looper,那么就会报错“Can`t create handler inside thread that has not called Looper.prepare()”解决方法有两个:为当前线程创建Looper即可,像上述代码中workHandler,或者在一个有Looper的线程中创建Handler也行,就像上述代码中的mainHandler一样;

⑥调用Handler的post方法会将一个Runnable投递到Handler内部的Looper中去处理,也可以通过Handler的send方法来发送一个消息,这个消息同样会在Looper中去处理。其实post方法最终也是通过send方法来完成的。每当Looper发现有新消息到来时,就会处理这个消息,最终消息中的Runnable的run方法或者Handler的handleMessage方法就会被调用。注意Looper是运行在创建Handler所在的线程中的,这样一来Handler中的业务逻辑就被切换到创建Handler所在的线程中去执行了;

⑦Looper的工作原理:Looper在Android的消息机制中扮演着消息循环的角色,具体来说就是它会不停地从MessageQueue中查看是否有新消息,如果有新消息就会立刻处理,否则就一直阻塞在那里。注意关注一些重要的Looper的方法:

  • Looper.prepare()-为当前线程创建一个Looper;
  • Looper.loop()-开启消息循环,只有调用该方法,消息循环系统才会开始循环;
  • Looper.prepareMainLooper()-为主线程也就是ActivityThread创建Looper使用;
  • Looper.getMainLooper()-通过该方法可以在任意地方获取到主线程的Looper;
  • Looper.quit() Looper.quitSafely()-退出Looper,自主创建的Looper建议在不使用的时候退出

⑧ActivityThread主线程通过ApplicationThread和AMS进行进程间通信

到此这篇关于Android中Handler、Thread、HandlerThread三者的区别的文章就介绍到这了,更多相关Android中Handler、Thread、HandlerThread三者的区别内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Android中Handler、Thread、HandlerThread三者的区别

本文链接: https://www.lsjlt.com/news/155349.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android中Handler、Thread、HandlerThread三者的区别
    目录一、前期知识储备二、三者的区别三、HandlerThread的使用一、前期知识储备 (1)Handler类,上官方文档,Handler public class Handler....
    99+
    2024-04-02
  • Android中Handler、Thread、HandlerThread有什么区别
    在Android中,Handler、Thread和HandlerThread是用于处理异步任务的三个重要类。它们之间的区别如下:1....
    99+
    2023-08-09
    Android
  • Android中Handler、Thread和HandlerThread有什么区别
    Handler是Android中用来处理消息和线程间通信的工具,主要用于将消息发送到消息队列,并在指定的时间处理这些消息。Han...
    99+
    2024-03-01
    android
  • cookie 、sessionstorage 、localstorage三者的区别
    一、什么是cookie 储存在用户本地终端上的数据,是网站为了识别用户和跟踪会话而存储在用户本地终端中的文本数据。 2、Cookie是保存在客户端的纯文本文件。比如txt文件。所谓的客户端就是我们自己的本地电脑。 二、什么是sessi...
    99+
    2023-08-19
    javascript 前端 服务器
  • MySQL execute、executeUpdate、executeQuery三者的区别
    MySQL是一种广泛使用的关系型数据库管理系统,用于存储和管理数据。在MySQL中,有三个常用的方法来执行SQL语句:execute...
    99+
    2023-08-17
    MySQL
  • C#中Backgroundworker与Thread的区别
    目录1.Backgroundworker2.Thread3.总结最近项目要用到,窗体Form程序要在后台开启几个子线程,负责和其他端进行通信,异步读写,并且来更改UI。在网上查了有B...
    99+
    2024-04-02
  • C++中const char*、char const*、char * const三者的区别
    目录一、const char *ptr;二、char const *ptr;三、char * const ptr;C/C++ 中关于以下三种定义: const char *...
    99+
    2024-04-02
  • java中BIO、NIO、AIO三者有什么区别
    这篇文章给大家介绍java中BIO、NIO、AIO三者有什么区别,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、BIO(Blocking IO,也被称作old IO)同步阻塞模型,一个客户端连接对应一个处理线程对于每...
    99+
    2023-06-14
  • gps、gis、rs三者的区别是什么
    今天就跟大家聊聊有关gps、gis、rs三者的区别是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。GPS(Global Positioning System)是全球(卫星)定位系...
    99+
    2023-06-15
  • Java、Javascript、Javaweb三者的区别及说明
    目录首先说一下java 与 javaweb之间的关系再者,说一下Java与Javascript之间的关系一、什么是Javascript二、什么是Java三、Javascript名字的...
    99+
    2023-02-16
    Java Javascript Javaweb的区别 Java Javascript的区别 Javascript Javaweb的区别
  • java中String、StringBuilder、StringBuffer三者有什么区别
    这篇文章给大家介绍java中String、StringBuilder、StringBuffer三者有什么区别,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。可变性首先,String是字符串,我们一般这样声明:String...
    99+
    2023-06-06
  • JDK1.8、JDK1.7、JDK1.6三者的区别有哪些
    这篇文章给大家介绍JDK1.8、JDK1.7、JDK1.6三者的区别有哪些,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、基本性质底层使用原生数组实现,实现RandomAccess接口,可以随机访问,随机访问指的是下...
    99+
    2023-05-30
    jdk1.8 jdk1.7 jdk1.6
  • mysql、alisql、access三者的区别是什么
    mysql、alisql、access三者的区别是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。  MySQL是一个关系型数据库管理系统,...
    99+
    2024-04-02
  • golang中uint8、int8和byte三者的区别是什么
    今天就跟大家聊聊有关golang中uint8、int8和byte三者的区别是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。简单说明uint8与byte可以说是一样的,因为文档中有...
    99+
    2023-06-14
  • MySQL中char、varchar和text三者的区别是什么
    今天就跟大家聊聊有关MySQL中char、varchar和text三者的区别是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。具体说明:char:...
    99+
    2024-04-02
  • C#中Abstract 、Virtual和Override三者的区别是什么
    C#中Abstract 、Virtual和Override三者的区别是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 abstract 修饰符指示所修饰的内容缺少实现或未完...
    99+
    2023-06-15
  • Mysql、SqlServer和Oracle三者的区别是什么
    Mysql、SqlServer和Oracle三者的区别是什么?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一、MySQL优点:体积小、速度...
    99+
    2024-04-02
  • Apply、Map和Aplymap三者的区别是什么
    Apply、Map和Aplymap三者的区别是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。首先,来个总结apply:应用...
    99+
    2024-04-02
  • map()、apply()、applymap()三者在pandas中有什么区别
    map()、apply()、applymap()三者在pandas中有什么区别?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。将通过实例来演示三者的区别toward_dict&n...
    99+
    2023-06-06
  • Python中赋值、浅拷贝、深拷贝三者的区别
    本篇文章为大家展示了Python中赋值、浅拷贝、深拷贝三者的区别,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。python有哪些常用库python常用的库:1.requesuts;2.scrapy;...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作