Messenger是什么?
- Messenger是对AIDL的封装,AIDL又是基于Binder机制实现的,使用Messenger能使我们更简单的实现进程间通信
- 优势在于我们可以免于自己去定义.aidl文件,使用系统中提前定义好的Messenger.aidl
- Messenger通常和Message、Handler一起使用
Messenger中封装了Handler,通过Messenger.send(Message)最终也就是调用了Handler.sendMessage()
Messenger流程
- 在客户端中启动一个服务,可以得到这个服务的serviceMessenger,然后通过serviceMessenger发送当前客户端的clientMessenger给服务端,这时候就实现了双向绑定。
Messenger用法
- 将MyService放入单独的进程中android:process=":remote"
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"
android:process=":remote" />
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.vision.mymessager", "com.vision.mymessager.MyService"));
bindService(intent, serviceConnection, BIND_AUTO_CREATE);
- MainActivity中
- MainActivity可以通Intent传递信息到另一个进程的Service
- bindService调用后,启动计时器Counting,这时候并没有回调信息到主进程(MainActivity),当点击事件触发后,MainActivity发送Message并附加clientMessenger到Service,Service接收到消息后,保存clientMessenger到当前进程中,然后计时器中的clientMessenger不为空,开始向主进程发送消息
package com.vision.mymessager
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.os.*
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
private const val TAG = "MainActivity"
class MainActivity : AppCompatActivity() {
private var handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg.what) {
MSG_FROM_SERVICE -> {
Log.d(TAG, "handleMessage: ${msg.data.getString(MSG_KEY)}")
}
}
}
}
private var clientMessenger: Messenger = Messenger(handler)
private var serviceMessenger: Messenger? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent(this, MyService::class.java)
intent.putExtra(MSG_KEY, "test")
bindService(intent, object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
serviceMessenger = Messenger(service)
}
override fun onServiceDisconnected(name: ComponentName?) {
serviceMessenger = null
}
}, BIND_AUTO_CREATE)
}
fun onClick(view: View) {
val msg = Message.obtain()
val bundle = Bundle()
bundle.putString("key", "msg from client")
msg.what = MSG_FROM_CLIENT
msg.data = bundle
msg.replyTo = clientMessenger
serviceMessenger?.send(msg)
}
}
package com.vision.mymessager
import android.app.Service
import android.content.Intent
import android.os.*
import android.util.Log
import java.util.concurrent.ScheduledThreadPoolExecutor
import java.util.concurrent.TimeUnit
private const val TAG = "MyService"
const val MSG_FROM_SERVICE = 0
const val MSG_FROM_CLIENT = 1
const val MSG_KEY = "msg_key"
class MyService : Service() {
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
when (msg.what) {
MSG_FROM_CLIENT -> {
Log.d(TAG, "handleMessage: ${msg.data.getString(MSG_KEY)}")
val bundle = Bundle()
bundle.putString(MSG_KEY, "msg from service")
msg.what = MSG_FROM_SERVICE
msg.data = bundle
clientMessenger = msg.replyTo
clientMessenger?.send(msg)
}
}
}
}
private var clientMessenger: Messenger? = null
private var serviceMessenger = Messenger(handler)
override fun onBind(intent: Intent): IBinder {
val value = intent.getStringExtra(MSG_KEY)
Log.d(TAG, "onBind: $value")
return serviceMessenger.binder
}
override fun onCreate() {
super.onCreate()
counting()
}
private var threadPool = ScheduledThreadPoolExecutor(1)
private fun counting() {
Log.d(TAG, "counting: ")
val bundle = Bundle()
var i = 0
threadPool.scheduleAtFixedRate({
Log.d(TAG, "onBind: $i")
bundle.putString(MSG_KEY, "${i++}")
val msg = Message.obtain()
msg.what = MSG_FROM_SERVICE
msg.data = bundle
clientMessenger?.send(msg)
}, 0, 1000, TimeUnit.MILLISECONDS)
}
override fun onDestroy() {
super.onDestroy()
threadPool.shutdownNow()
handler.removeCallbacksAndMessages(null)
}
}
Messenger源码
- Messenger构造方法一(创建clientMessenger)
调用了Handler的getIMessenger
public Messenger(Handler target) {
mTarget = target.getIMessenger();
}
- Messenger构造方法二(得到serviceMessenger)
public Messenger(IBinder target) {
mTarget = IMessenger.Stub.asInterface(target);
}
- 在Handler中有如下代码
- getIMessenger方法获取MessengerImpl
- MessengerImpl又继承自IMessenger.Stub,并且实现了send方法,send方法最终调用的是Handler.sendMessage
@UnsupportedAppUsage
final IMessenger getIMessenger() {
synchronized (mQueue) {
if (mMessenger != null) {
return mMessenger;
}
mMessenger = new MessengerImpl();
return mMessenger;
}
}
private final class MessengerImpl extends IMessenger.Stub {
public void send(Message msg) {
msg.sendingUid = Binder.getCallingUid();
Handler.this.sendMessage(msg);
}
}
参考资料