Android多线程异步通信模型-Handler & Looper

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对象放入到消息队列中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李来群

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值