IPC初探(二)
本文将会介绍Messenger通信。
Mesenger是一种轻量级的IPC方案。它通过传递Message来实现数据的进程间传递。
它的底层实现是AIDL。
Messenger工作原理:
需求描述:
- C端向S端跨进程发送msg,并封装一个bundle数据对象
- S接收msg,读取bundler数据,并向C端返回一条新的msg,并封装一个新的bundlB数据对象。
编码实现:
服务端进程
- 我们创建一个服务
MessengerService
来处理客户端的连接请求,并为这个Servie指定新的进程名。 - 在
MessengerService
创建一个Handler,并通过它创建一个Messenger对象。 - 在
MessengerService
的onBind
方法中返回这个Messenger低层的Binder对象。 代码如下:
public class MessengerService extends Service { private static final String TAG = "MessengerService"; public MessengerService() { } private static class MessengerHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MessengerConst.MSG_FROM_CLIENT: Log.d(TAG,"msg from client:" + msg.getData().getString("msg")); Messenger client = msg.replyTo; Message replyMsg = Message.obtain(null,MessengerConst.MSG_FROM_SERVICE); Bundle bundle = new Bundle(); replyMsg.setData(bundle); bundle.putString("reply", "来自服务断的回复"); try { client.send(replyMsg); } catch (RemoteException e) { e.printStackTrace(); } break; default: super.handleMessage(msg); } } } private static final Messenger mMessenger = new Messenger(new MessengerHandler()); @Override public IBinder onBind(Intent intent) { Log.d(TAG, "Service onBind"); return mMessenger.getBinder(); } }
- 我们创建一个服务
客户端进程
- 需要绑定服务端的Service。
- 绑定成功后用服务端返回的IBinder创建一个Messenger。这个Messenger可以向服务端发送msg。
- 还需要创建一个新的Messenger对象,这个Messenger通过msg的replyTo参数传递给服务端。
代码如下:
public class MessengerActivity extends AppCompatActivity { private static final String TAG = "MessengerActivity"; private Messenger mService; private boolean bindService = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_messenger); findViewById(R.id.btnSendMsgToService).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MessengerActivity.this, MessengerService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } }); } private static class MessengerHandler extends Handler { @Override public void handleMessage(Message msg) { switch (msg.what) { case MessengerConst.MSG_FROM_SERVICE: Log.d(TAG,"msg from client:" + msg.getData().getString("reply")); break; default: super.handleMessage(msg); } } } private Messenger replyMessenger = new Messenger(new MessengerHandler()); private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { bindService = true; mService = new Messenger(service); Message msg = Message.obtain(null,MessengerConst.MSG_FROM_CLIENT); Bundle bundle = new Bundle(); bundle.putString("msg","Hi, i am client."); msg.setData(bundle); msg.replyTo = replyMessenger; try { mService.send(msg); } catch (RemoteException e) { Log.e(TAG, "remote exception"); e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onDestroy() { if (bindService){ unbindService(mConnection); } super.onDestroy(); } }
可以在这里获取完整的代码:
关于代码的一些细节:
在运行示例的时候,如果你看不到远程服务的Log,可能是因为选择的进程是默认进程,需要切换监视进程:
运行产生的日志:
客户端:
04-22 02:08:07.083 21045-21045/com.dou.ipcsimple D/MessengerActivity: msg from client:来自服务断的回复
服务端:
04-22 02:08:07.083 21231-21231/com.dou.ipcsimple:remote2 D/MessengerService: Service onBind
msg from client:Hi, i am client.