Android消息机制Handler、Thread、HandlerThread理解


最近重新看回AMS的启动过程,发现AMS的构造方法里创建了几个前台线程,有以下几点疑问。

//创建名为"ActivityManager"的前台线程,并获取mHandler
mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
//通过UiThread类,创建名为"android.ui"的线程
mUiHandler = mInjector.getUiHandler(this);
//创建名为"ActivityManager:procStart"的前台线程,并获取mProcStartHandler
mProcStartHandlerThread = new ServiceThread(TAG + ":procStart", THREAD_PRIORITY_FOREGROUND, false /* allowIo */);	

疑问

  • HandlerThread是什么?
  • MainHandler初始化传入的是前台线程的Looper对象,这说明什么?
  • MainHandler收到消息队列的消息后,执行代码跑在主线程还是前台线程?

Handler

1.Handler的一般用法

在应用程序开发中,如果直接在主线程中跑耗时的操作(比如下载),会导致主线程阻塞,超过5s会触发ANR,这时候我们会新开一个子线程执行耗时操作,同时通过Handler来通知主线程更新UI(比如下载状态更新或者进度条更新啥的)。因此Handler可以实现子线程和UI线程的消息通信;

以下是一个线程中Handler,Looper和MessageQueue的关系图;
在这里插入图片描述

Looper 一个线程可以产生一个 Looper 对象,由它来管理此线程里的 MessageQueue( 消息队列 ) 和对消息进行循环。
Handler 你可以构造 Handler 对象来与 Looper 沟通,以便 push 新消息到 MessageQueue 里 ; 或者接收 Looper 从 Message Queue 取出 所送来的消息。
Message Queue( 消息队列 ) 用来存放线程放入的消息。
Message 是线程间通讯的消息载体。两个码头之间运输货物,Message充当集装箱的功能,里面可以存放任何你想传递的消息。

看到这里就明白了为什么:如果一个线程要处理消息,那么它必须拥有自己的Looper,并不是Handler在哪里创建,就可以在哪里处理消息,只是主线程(ActivityThread)初始化的时候默认创建了Looper。

2.HandlerThread是什么

上面提到子线程可以通过Handler给UI线程发消息,那么反过来UI线程给子线程发消息通知呢?这里就引入了HandlerThread;
HandlerThread:一个继承自Thread的类HandlerThread,Android中没有对Java中的Thread进行任何封装,而是提供了一个继承自Thread的类HandlerThread类,这个类对Java的Thread做了很多便利的封装。
1、比如HandlerThread在start()后会创建一个Looper;
2、可以使用这个Looper实例化一个Handler,这个Handler可以运行在其他线程,比如UI线程;

3.MainHandler初始化传入的是前台线程的Looper对象,这说明什么?

回到上面的疑问,HandlerThread本质上就是一个线程,只是start()后创建了自己的Looper对线,因此

mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());

意味MainHandler使用的是名为"ActivityManager"前台线程的Looper实例;因此通过MainHandler实例发送的消息,都是往名为"ActivityManager"前台线程发。

4.MainHandler收到消息队列的消息后,执行代码跑在主线程还是前台线程?

答案是跑在前台线程。Handler使用哪个线程的Looper实例化,对应的消息处理或者runnable跑在对应的线程。

以上理解来源于自己做了实验,同时参考了Handler、Thread、HandlerThread三者的区别

猜你喜欢

转载自blog.csdn.net/lgglkk/article/details/125359950