简单介绍
Messenger是基于binder实现的轻量化的IPC通信方式。
服务端代码
以下是关于继承service实现的服务的相关代码,重点是onBind方法的返回对象,会在client端连接后通过binder获取到。
package com.example.test.messenger;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
@Nullable
@Override
public IBinder onBind(Intent intent) {
Messenger messenger = new Messenger(new Handler(this.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
Log.d(TAG, "MessengerService handleMessage msg.what = " + msg.what);
switch (msg.what) {
case 1: // 客户端发送消息时携带的what标记
String bundleValue = msg.getData().getString("bundle_key");
Log.d(TAG, "bundleValue = " + bundleValue);
// 获取到client端Messenger对象
Messenger clientMessenger = msg.replyTo;
Log.d(TAG, "clientMessenger = " + clientMessenger);
Message toClientMsg = Message.obtain();
toClientMsg.what = 2;
try {
// 发送消息给request client
clientMessenger.send(toClientMsg);
Log.d(TAG, "clientMessenger send success");
} catch (RemoteException e) {
Log.e(TAG, "clientMessenger send fail");
throw new RuntimeException(e);
}
break;
}
}
});
// server返回binder对象给client
return messenger.getBinder();
}
}
客户端代码
通过bindService与服务端建立连接,连接成功后会获取到服务端的IBinder对象,然后构造出服务端的Messenger serverMessenger 对象,最后通过serverMessenger来send消息给服务端并进行通信,消息中携带的replyTo是用于服务端获取到客户端消息后给予回复。
package com.example.test.messenger;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.example.test.R;
public class MessengerActivity extends AppCompatActivity {
private static final String TAG = "MessengerActivity";
private ClientServiceConnection mClientServiceConnection;
private Messenger clientMessenger;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
clientMessenger = new Messenger(new Handler(this.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
Log.d(TAG, "clientMessenger msg.what = " + msg.what);
}
});
Intent intent = new Intent();
intent.setAction("messenger.action.test.message");
intent.setPackage("com.example.test");
mClientServiceConnection = new ClientServiceConnection();
bindService(intent, mClientServiceConnection, Context.BIND_AUTO_CREATE);
findViewById(R.id.btn_send_msg).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "click send msg to server");
Message toServerMsg = Message.obtain();
toServerMsg.what = 1;
// 给server端设置reply的client端的传信者
toServerMsg.replyTo = clientMessenger;
Log.d(TAG, "clientSend = " + clientMessenger);
// 注意不可以传递非parcel的对象,例如toServerMsg.obj = "11111";是不被允许的 ,只能给obj赋值为parcel类型才是可以的
Bundle bundle = new Bundle();
bundle.putString("bundle_key", "123456");
toServerMsg.setData(bundle);
try {
serverMessenger.send(toServerMsg);
Log.d(TAG, "serverMessenger send success");
} catch (RemoteException e) {
Log.e(TAG, "serverMessenger send fail");
throw new RuntimeException(e);
}
}
});
}
private Messenger serverMessenger;
private class ClientServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "onServiceConnected");
serverMessenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "onServiceDisconnected");
}
}
}
AndroidManifest.xml配置
<service
android:name=".messenger.MessengerService"
android:exported="true">
<intent-filter>
<action android:name="messenger.action.test.message" />
</intent-filter>
</service>
<activity
android:name=".messenger.MessengerActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
日志输出
关于使用Messenger双向通信时的打印日志如下所示
04-22 17:24:12.170 16151 16151 D MessengerActivity: onServiceConnected
04-22 17:24:57.742 16151 16151 D MessengerActivity: click send msg to server
04-22 17:24:57.742 16151 16151 D MessengerActivity: clientSend = android.os.Messenger@a7d382e
04-22 17:24:57.743 16151 16151 D MessengerActivity: serverMessenger send success
04-22 17:24:57.752 16151 16151 D MessengerService: MessengerService handleMessage msg.what = 1
04-22 17:24:57.752 16151 16151 D MessengerService: bundleValue = 123456
04-22 17:24:57.752 16151 16151 D MessengerService: clientMessenger = android.os.Messenger@a7d382e
04-22 17:24:57.753 16151 16151 D MessengerService: clientMessenger send success
04-22 17:24:57.753 16151 16151 D MessengerActivity: clientMessenger msg.what = 2