Messenger
问题
Messenger 是什么?和 AIDL 有什么区别?
答案
Messenger 原理
Messenger 是 AIDL 的轻量封装,底层仍然基于 Binder,但所有消息在 Server 端的 Handler 中串行处理,不需要考虑线程同步:
Server 端
class MessengerService : Service() {
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_SAY_HELLO -> {
val name = msg.data.getString("name")
Log.d("Server", "Hello from $name")
// 回复 Client
msg.replyTo?.send(Message.obtain(null, MSG_REPLY).apply {
data = Bundle().apply { putString("result", "Welcome, $name!") }
})
}
}
}
}
private val messenger = Messenger(handler)
override fun onBind(intent: Intent): IBinder = messenger.binder
companion object {
const val MSG_SAY_HELLO = 1
const val MSG_REPLY = 2
}
}
Client 端
class MessengerActivity : AppCompatActivity() {
private var serverMessenger: Messenger? = null
// Client 也创建 Messenger 接收回复
private val clientHandler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when (msg.what) {
MessengerService.MSG_REPLY -> {
val result = msg.data.getString("result")
Log.d("Client", "Reply: $result")
}
}
}
}
private val clientMessenger = Messenger(clientHandler)
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
serverMessenger = Messenger(service)
sendMessage()
}
override fun onServiceDisconnected(name: ComponentName) {
serverMessenger = null
}
}
private fun sendMessage() {
val msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO).apply {
data = Bundle().apply { putString("name", "Client") }
replyTo = clientMessenger // 设置回复的 Messenger
}
serverMessenger?.send(msg)
}
}
Messenger vs AIDL
| 特性 | Messenger | AIDL |
|---|---|---|
| 复杂度 | 简单 | 较复杂 |
| 线程模型 | 串行(Handler) | 并发(Binder 线程池) |
| 数据类型 | Message + Bundle | 自定义接口 |
| 适用场景 | 简单消息传递 | 复杂接口、高频调用 |
| 同步调用 | ❌ 只能异步 | ✅ 支持 |
选型建议
- 简单消息传递(如通知、状态同步)→ Messenger
- 复杂接口方法(如获取数据列表、回调)→ AIDL
常见面试问题
Q1: Messenger 为什么是线程安全的?
答案:
Messenger 底层使用 IMessenger.aidl(系统内置),所有消息最终通过 Handler.sendMessage() 投递到 Handler 绑定的 Looper 的 MessageQueue 中。Looper 是单线程循环处理消息,因此所有请求天然串行执行,不存在并发竞争问题。