Kotlin进程通信------Messenger
Posted 战国剑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin进程通信------Messenger相关的知识,希望对你有一定的参考价值。
进程通信原理与Binder底层说明,可参考:https://zhuanlan.zhihu.com/p/35519585
本文主要介绍应用层上如何用Kotlin来使用Messenger进行进程通讯。
Messenger是对底层Binder进行封装后的一套系统框架,在进程间通讯的表现是串行通讯。假设有进程A和进程B。如果要进行多次数据通讯,会是A-B-A-B-......这样的模式。
Messenger的做法,简要说明就是:两个进程A(client)、B(service),A将一个Messenger信息发送到B,B通过handler来接收来自A的信息,并将想要返回的信息返回A。
一、server服务端
代码如下,这里比较绕的是这句代码:
val fromClient = msg.replyTo
此处的 msg.replyTo,是客户端发送过来的包含客户端handler的Messenger对象。
那么,后续的fromClient.send(any),做的就是把数据传回给客户端的handler做处理。
class MessengerService :Service() {
private val handler: Handler = @SuppressLint("HandlerLeak")
object:Handler(){
override fun handleMessage(msg: Message) {
when(msg.what){
MSG_FROM_CLIENT -> {
println("接收到客户端信息")
println(msg.data.get("TestKey"))
val fromClient = msg.replyTo
val currentMsg:Message = Message.obtain(null, MSG_FROM_CLIENT)
val bundle:Bundle = Bundle()
bundle.putString("KeyFromServer","这是服务端的回复")
currentMsg.data = bundle
fromClient.send(currentMsg)
}
else -> println("其他信息")
}
}
}
override fun onBind(intent: Intent?): IBinder? {
return Messenger(handler).binder
}
}
二、client客户端
客户端要做的操作,一是连接服务端,二是发送信息给服务端,并得到服务端的返回
代码中,需要注意的代码块是:
override fun onServiceConnected(name: ComponentName?, service: IBinder?) { messenger = Messenger(service) val msg: Message = Message.obtain(null, MSG_FROM_CLIENT) val bundle:Bundle = Bundle() bundle.putString("TestKey","TestValue") msg.data = bundle msg.replyTo = Messenger(handler) messenger.send(msg) }
1、messenger = Messenger(service),该service是服务端Hander被Binder包装后返回的(具体看服务端的OnBinder方法)。因此,经此发送的数据,将被服务端的Handler接收与处理
2、msg.replyTo = Messenger(handler),告知服务端,客户端处处理,服务端返回数据的,是哪个Handler。
整体代码如下:
class MessengerActivity : AppCompatActivity() {
lateinit var messenger: Messenger
lateinit var serviceConnection:ServiceConnection
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_messenger)
messengerTest.setOnClickListener { testSendMessageByMessenger() }
}
private fun testSendMessageByMessenger(){
val intent = Intent(this, MessengerService::class.java)
serviceConnection = object : ServiceConnection {
override fun onServiceDisconnected(name: ComponentName?) {
println("onServiceDisconnected $name")
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
messenger = Messenger(service)
val msg: Message = Message.obtain(null, MSG_FROM_CLIENT)
val bundle:Bundle = Bundle()
bundle.putString("TestKey","TestValue")
msg.data = bundle
msg.replyTo = Messenger(handler)
messenger.send(msg)
}
}
val type = Context.BIND_AUTO_CREATE
bindService(intent,serviceConnection,type)
}
override fun onDestroy() {
super.onDestroy()
serviceConnection?.let { unbindService(serviceConnection) }
}
val handler:Handler =@SuppressLint("HandlerLeak") object :Handler(){
override fun handleMessage(msg: Message) {
println("收到service服务端消息")
when(msg.what){
MSG_FROM_CLIENT -> {
println("${msg.data.getString("KeyFromServer")}")
}
}
}
}
}
最后,在manifest中加上配置即可
<service
android:name=".messenger.MessengerService"
android:label="@string/messenger_name"
android:process=":messenger_remote" />
以上是关于Kotlin进程通信------Messenger的主要内容,如果未能解决你的问题,请参考以下文章