原理: 使用 Messenger 可以在进程间传递数据, 实现一对多的处理. 其内部实现, 也是基于 aidl 文件, 这个aidl位于: frameworks/base/core/java/android/os/IMessenger.aidl.
一 服务端实现
1 这种方式是通过BindService 实现的 所以 创建一个MyService继承Service 重写 onBind方法 ,只不过此次返回的Ibinder实现类不是自定义的继承Binder的实体。而是通过Messenger.getBinder() 获取一个Ibinder实现类;
2 使用Handler对象【用于处理客户端发来的消息 同时在handleMessage方法里获取客户端Messenger对象】 构造一个 服务端的Messenger对象 用于连接客户端用【即】
public IBinder onBind(Intent intent) {
// 此时返回的不是绑定服务自己实现的Ibinder实现类 而是 从创建的messager里获取Ibinder
return messenger.getBinder();
}
3 服务端发消息是通过 Messenger client = msg.replyTo; 获取客户端指定回复的Messenger 发送的
下边为服务端代码
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
// 此时返回的不是绑定服务自己实现的Ibinder实现类 而是 从创建的messager里获取Ibinder
return messenger.getBinder();
}
/**
* service 里定义 messenger
*/
Messenger messenger = new Messenger(new MyHandler());
// 用于处理 客户端发来的消息 和 获取 客户端的Messenger 用于发送回复客户端的消息
private class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 100:
Bundle data = msg.getData();
String msgContent = data.getString("msg");
Log.e("flag", "-----服务端收到 客户端发来的消息:"+msgContent);
// 1 获取客户端的messager用于发送回复它的消息 根据 Message.replyTo 获取客户端【例如activity】里的messager
Messenger client = msg.replyTo;
// 2 绑定数据
Bundle replyData = new Bundle();
replyData.putString("reply", "你的消息<" + msgContent + ">,我已收到");
// 创建恢复消息
Message replyMsg = Message.obtain();
replyMsg.what = 100;
replyMsg.setData(replyData);
try {
client.send(replyMsg);
} catch (RemoteException e) {
Log.e("flag", "", e);
}
break;
}
}
}
}
清单文件注册 服务 另起进程
<service
android:name=".binderservice.MyService"
android:exported="true"
android:process=":remote">
<intent-filter>
<action android:name="com.example.MyService" />
</intent-filter>
</service>
二 客户端实现
1 绑定 service 在 ServiceConnection 服务连接的 回调方法里 onServiceConnected 获取服务端的Messenger 用于 客户端给服务端发消息
2 创建Handler对象【处理 服务端 回复的消息 】
3 根据Handler对象 构造 客户端的Messenger
4 通过 onServiceConnected 里 得到的服务端的Messenger对象开始给服务端发消息 。 而发消息时是把客户端创建的Messenger指定给服务端【告诉它用这个回复消息】 msg.replyTo = ClentMessenger;
以下为客户端代码
public class Main5Activity extends AppCompatActivity {
// 发送消息给服务端的Messenger 绑定服务后在onServiceConnected里 根据绑定服务返回的Ibinder new的
private Messenger serviceMessenger;
// 创建客户端的Messager 只用于告诉服务端用什么发送回复消息的 关键代码在红色
private Messenger ClentMessenger = new Messenger(new ClientHandler());
// 收到服务端发来的消息
private class ClientHandler extends Handler {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 100:
Bundle bundle = msg.getData();
String info = bundle.getString("reply");
Log.e("flag", "--------------客户端 收到了 服务端返回的消息:" + info);
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main5);
findViewById(R.id.tv_send_broadcast).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendMessager();
}
});
}
@Override
protected void onStart() {
super.onStart();
bindService();
}
private void bindService() {
Intent intent = new Intent(this, MyService.class);
bindService(intent, new MyServiceConnection(), Context.BIND_AUTO_CREATE);
}
private void sendMessager() {
// 向服务端发送数据
try {
// 1 获取消息对象
Message msg = Message.obtain();
msg.what = 100;
// 2 设置发送数据信息
Bundle data = new Bundle();
data.putString("msg", "客户端发来的");
msg.setData(data);
// 3 设置服务端回复的Messenger 【告诉服务端回复的messager 它是客户端自己创建的】
msg.replyTo = ClentMessenger;
// 4 使用绑定服务后的创建的 Messager发送消息
serviceMessenger.send(msg);
} catch (RemoteException e) {
Log.e("flag", "", e);
}
}
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 绑定服务后 根据绑定后返回的 IBinder 创建给 服务端发消息的 Messenger
serviceMessenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.e("flag", "----------onServiceDisconnected");
}
}
}
完成简单的跨进程通信