Messenger 信使 也是进程间通信的一种方式,但是它的好处在于不用像aidl 一样必须要定义aidl 接口,然后通过接口来通信,本质上messenger 的实现底层也是通过aidl 实现的。
实现原理是客户端通过绑定服务端service ,通过返回的IBundle,生成获取到服务端的Messenger对像,然后通过服务端的Messenger 对象将客户端的Messenger 发送到服务端,这样两端各自持有对方的Messenger 对像,而每个messenger 都会绑定各自的handler对象,所以当发送消息时handler 就会收到,然后就可以愉快的通信了。
本篇代码将和上篇aidl 使用相同的项目多进程间通信AIIDL使用
步骤如下:
1.服务端 新建两个项目,一个用于服务端app (aidlapplication),一个用于客户端app(clientservice)
2.服务端 创建服务端service ,创建Messenger 并通过getBinder获取 IBinder ,使用onBind返回给客户端
3.客户端绑定服务端service,通过IBinder 获取到服务端Messenger
4.将客户端的Messenger 发送到服务端
5.两端可以互相发送消息了
1.服务端 新建两个项目,一个用于服务端app (aidlapplication),一个用于客户端app(clientservice)
这步就不多说了,名字大家可以随意取,这里只是便于分辩
2.服务端 创建服务端service ,创建Messenger 并通过getBinder获取 IBinder ,使用onBind返回给客户端
public class MessengerService extends Service {
private static final String TAG = "MessengerService";
Messenger clientMessenger;
int messageid=0;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what==0) {
//获取客户端的messenger对象,及初始消息
clientMessenger=msg.replyTo;
}else {
Bundle bundle=msg.getData();
Log.d(TAG, msg.what +"" + "handleMessage: 收到客户端的消息"+ bundle.getString("ms"));
//发送消息给客户端我收到你的消息了
Bundle sbundle=new Bundle();
Message message=Message.obtain();
sbundle.putString("cms","这是一条服务端发来的消息" + messageid++);
message.setData(sbundle);
message.what=0x02;
try {
clientMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
};
//创建服务端的messenger 对象
Messenger messenger=new Messenger(handler);
}
这里我们通过onBind 返回了一个IBinder 接口 ,实际是从Messenger中获取到的IBinder 接口,而Messenger 本身在初始化时又绑定了一个handler ,当客户端发送消息时服务端的handler 就会收到消息,replyTo 方法用于获取客户端的Messenger对象。
很重要的一点,服务端要注册
<service
android:name=".MessengerService"
android:enabled="true"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.example.service.messenger"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</service>
3.客户端绑定服务端service,通过IBinder 获取到服务端Messenger
通过intent 绑定服务
Intent intent = new Intent();
intent.setPackage("com.example.aidlapplication");
intent.setAction("com.example.service.messenger");
bindService(intent, connection, BIND_AUTO_CREATE);
这里的package是服务端的包名,action 是注册时定义的,用于匹配启动绑定服务。
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceMessenger = new Messenger(service);
if (serviceMessenger == null) {
try {
throw new IllegalAccessException("绑定成功但是 serviceMessenger 是 null");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
绑定成功后我们获取到了,服务端的Messenger对象serviceMessenger
4.将客户端的Messenger 发送到服务端
通过绑定获取到了服务端的Messenger对象serviceMessenger 然后通过这个serviceMessenger 将客户端的messenger 发送到
服务端。
这里需要客户端先new 一个Messenger cMessenger然后绑定一个handler .
Message message = Message.obtain();
message.what = 0x00;
message.replyTo = cMessenger;
Bundle bundle=new Bundle();
message.setData(bundle);
try {
//发送客户端Messenger 到服务端,本意在建立链接
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
5.两端可以互相发送消息了
通过上边的步骤我们两个端各自获取到了对方的Messenger 对象,就可以通过这个发送消息到对方了。
我将客户端的activity 全部粘出来
public class MessageActivity extends Activity {
StringBuilder stringBuilder=new StringBuilder();
private static final String TAG = "MessageActivity";
private Button mMessengerBindService;
private Button mMessengerSendMsToService;
private TextView mmessengerMsShow;
private Button messenger_send_messenger_to_service;
private Button messengerSendMsToService;
private TextView messengerMsShow;
Messenger serviceMessenger;
Handler serviceHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mesenge_layout);
initView();
Intent intent = new Intent();
intent.setPackage("com.example.aidlapplication");
intent.setAction("com.example.service.messenger");
bindService(intent, connection, BIND_AUTO_CREATE);
}
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
serviceMessenger = new Messenger(service);
if (serviceMessenger == null) {
try {
throw new IllegalAccessException("绑定成功但是 serviceMessenger 是 null");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
Handler cHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what != 0x00) {
stringBuilder.append("\n");
stringBuilder.append( msg.getData().getString("cms"));
Log.d(TAG, "handleMessage: 我收到了服务端发来的消息");
messengerMsShow.setText(stringBuilder.toString());
}else if(msg.what==0){
}
}
};
Messenger cMessenger = new Messenger(cHandler);
public void initView() {
messenger_send_messenger_to_service = findViewById(R.id.messenger_send_messenger_to_service);
messengerSendMsToService = findViewById(R.id.messenger_send_ms_to_service);
messengerMsShow = findViewById(R.id.messenger_ms_show);
messenger_send_messenger_to_service.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 0x00;
message.replyTo = cMessenger;
Bundle bundle=new Bundle();
message.setData(bundle);
try {
//发送客户端Messenger 到服务端,本意在建立链接
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
messengerSendMsToService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 0x02;
Bundle bundle=new Bundle();
bundle.putString("ms","我是客户端,我向服务端发送了一条请求");
message.setData(bundle);
try {
//发送客户端Messenger 到服务端
serviceMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
});
}
}
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<Button
android:id="@+id/messenger_send_messenger_to_service"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="绑定service" />
<Button
android:id="@+id/messenger_send_ms_to_service"
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="向服务端发送消息"/>
<TextView
android:id="@+id/messenger_ms_show"
android:layout_marginTop="40dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"/>
</LinearLayout>
资源下载地址:https://download.csdn.net/download/u013179982/12305267