【多线程通信】消息机制Handler
Handler的工作原理(消息机制)
消息处理包括消息的发送与接收,发送分为send和post,而post本质是由send实现的。
发送过程:
- 当handler.sendMessage后,MessageQueue的enqueueMessage会将消息入队;
- MessageQueue的next()会将消息返回给Looper的loop()
- handler.dispatchMessage对消息进行处理
处理过程:
- 先检查是否为post(通过msg.callback)
- 不是则判断handler初始化是否传入callback
- 没有或处理失败交由重写的handleMessage处理
ThreadLocal类
它是一个县城内部的数据存储类,通过它可以再指定线程中存取数据,它是handler能获取当前线程Looper的关键。虽然在不同线程中访问的是同一个ThreadLocal对象,却会获得不一样的值,这是因为它的get方法会从线程中取出一个数组,从数组中根据ThreadLocal当前索引去查找value
Looper工作原理
它会不断地从MessageQueue中查看是否有新消息,有则立即处理,没有则阻塞。它在创建时会同时创建MessageQueue并保存当前thread信息。Looper.loop()在MessageQueue的next不反悔消息而一直阻塞,若有返回则调用msg.target.dispatchMessage(msg)来处理消息,这里的dispatchMessage是在创建Hnadler时所使用的Looper中执行的,因此将处理过程切换到了指定的线程。(其中msg.target为发送它的handler)
MessageQueue原理
主要包括两个操作:插入和读取,分别对应enqueueMessage和next方法,enqueueMessage是向消息队列中插入一条信息。next方法是一个循环,若队列中没有消息,next方法会一直阻塞;当有新消息时,next会返回这条消息并从队列中移除它
线程工具
Thread和Runnable
AsyncTack
HandlerThread
1、HandlerThread产生背景
当系统有多个耗时任务需要执行时,每个任务都会开启一个新线程去执行耗时任务,这样会导致系统多次创建和销毁线程,从而影响性能。为了解决这一问题,Google提供了HandlerThread,HandlerThread是在线程中创建一个Looper循环器,让Looper轮询消息队列,当有耗时任务进入队列时,则不需要开启新线程,在原有的线程中执行耗时任务即可,否则线程阻塞
2、HanlderThread的特点、
HandlerThread本质上是一个线程,继承自Thread
HandlerThread有自己的Looper对象,可以进行Looper循环,可以创建Handler
HandlerThread可以在Handler的handlerMessage中执行异步方法
HandlerThread优点是异步不会堵塞,减少对性能的消耗
HandlerThread缺点是不能同时继续进行多任务处理,需要等待进行处理,处理效率较低
HandlerThread与线程池不同,HandlerThread是一个串行队列,背后只有一个线程
IntentService
1、IntentService是什么
IntentService是继承自Service并处理异步请求的一个类,其内部采用HandlerThread和Handler实现的,在IntentService内有一个工作线程来处理耗时操作,其优先级比普通Service高。当任务完成后,IntentService会自动停止,而不需要手动调用stopSelf()。另外,可以多次启动IntentService,每个耗时操作都会以工作队列的方式在IntentService中onHandlerIntent()回调方法中执行,并且每次只会执行一个工作线程
2、IntentService使用方法
创建Service继承自IntentService
覆写构造方法和onHandlerIntent()方法
在onHandlerIntent()中执行耗时操作