Actor模型
每个进程使用消息和其他进程进行通信,每个进程有个邮箱可以存储消息,进程通过检查邮箱的消息,然后采取行动,这其实就是现在的Actor模型。
Handler/Looper模型和Actor模型很像,不同的是Handler/Looper模型更多的是关注同一个进程内线程间的消息传递和处理;而Actor模型提供了一种更通用、更分布式的并发编程框架。
Handler/Looper模型
- 有一个MessageQueue的作用,这个的作用相当于Actor的邮箱(Mailbox)。
- 处理消息: Looper 则代表从头到尾依次获取邮箱中的消息(Mail或者Message),对应的方法为DispathMessage,然后调用对应的处理函数(Handler的handleMessage)。
- 发送消息: 调用handler的sendMsg可以向MessageQueue中发送消息。
一个线程只能有一个MessageQueue,一个Looper,但可以有多个Handler,每一个 Handler 都可以有它自己的消息处理逻辑。所有这些 Handler 对象共享同一个消息队列(由 Looper 管理)。
创建Handler时指定的是哪个线程的Looper,信息会发给对应的线程,消息处理函数由该线程来执行。举例:
//在Android中,不允许在子线程中进行UI操作,只能在主线程中执行
//但是,可以在子线程给主线程发消息,让主线程来处理
class MainActivity:AppCompatActivity()
{
val updateText = 1
val handler = object: Handler(Looper.GetMaininLooper())
{
override fun handleMessage(msg:Message)
{
when(msg.what)
{
updateText -> textView.text = "Nice to meet you"
}
}
}
override fun onCreate(savedInstanceState:Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
changeTextBtn.setOnClickListener{
thread{//创建子线程
val msg = Message()
msg.what = updateText
//将消息从子线程发给主线程,因为这个handler对应的Looper为主线程的
handler.sendMessage(msg)
}
}
}
}
一个线程如何给另一个线程发消息?
方法1: 获取Looper,然后根据这个Looper创建新的Handler
import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
private lateinit var workerHandler: Handler
private lateinit var workerLooper: Looper
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workerThread = Thread {
Looper.prepare()
workerLooper = Looper.myLooper()!!
Looper.loop()
}
workerThread.start()
// 小延迟以确保 Looper 初始化完成
Thread.sleep(500)
// 在主线程上创建一个 Handler,使用 worker 线程的 Looper
workerHandler = Handler(workerLooper) {
// 在 worker 线程上处理消息
println("Message received in Worker Thread: ${it.what}")
true
}
// 在主线程上发送一个消息到 worker 线程
val message = Message.obtain(null, 123)
workerHandler.sendMessage(message)
}
}
方法2: 获取到另一个线程的handler
import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class MainActivity : AppCompatActivity() {
private lateinit var workerHandler: Handler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val workerThread = Thread {
Looper.prepare()
workerHandler = Handler(Looper.myLooper()!!) {
// 在工作线程中处理消息
println("Message received in Worker Thread: ${it.what}")
true
}
Looper.loop()
}
workerThread.start()
// 小延迟以确保 Handler 初始化完成
Thread.sleep(500)
// 在主线程中发送一个消息到工作线程
val message = Message.obtain(null, 123)
workerHandler.sendMessage(message)
}
}
创建新的类,添加字段来保存Handler
import android.os.Handler
import android.os.Looper
import android.os.Message
class MyThread : Thread() {
var handler: Handler? = null
override fun run() {
Looper.prepare()
handler = Handler(Looper.myLooper()!!) {
// 处理消息的代码
true
}
Looper.loop()
}
}
// 在主线程中使用
val myThread = MyThread()
myThread.start()
// 确保 Handler 已被初始化
while (myThread.handler == null) {
Thread.yield()
}
// 使用 Handler 发送消息
val message = Message.obtain()
// 设置消息内容等
myThread.handler?.sendMessage(message)
Handler的postDelayed做了什么?
Handler对象的postDelayed(Runnable r, long delayMillis)方法用于在指定的延迟后将一个Runnable对象放入到消息队列中