A Preliminary Study of IPC (2)
This article will introduce Messenger communication.
Messenger is a lightweight IPC solution. It realizes the inter-process transfer of data by passing Message.
Its underlying implementation is AIDL.
How Messenger works:
Description of Requirement:
- The C-side sends msg to the S-side across processes and encapsulates a bundle data object
- S receives msg, reads bundler data, returns a new msg to C, and encapsulates a new bundleB data object.
Coding implementation:
server process
- We create a service
MessengerService
to handle client connection requests and specify a new process name for this Servie. - Create a
MessengerService
Handler and create a Messenger object from it. - Return the Binder object of the lower level of this Messenger in
MessengerService
the method of .onBind
code show as below:
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(); } }
- We create a service
client process
- Need to bind the Service on the server side.
- After the binding is successful, create a Messenger with the IBinder returned by the server. This messenger can send msg to the server.
- You also need to create a new Messenger object, which is passed to the server through the replyTo parameter of msg.
code show as below:
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(); } }
The complete code can be found here:
Some details about the code:
When running the example, if you can't see the Log of the remote service, it may be because the selected process is the default process and you need to switch the monitoring process:
Logs produced by running:
Client:
04-22 02:08:07.083 21045-21045/com.dou.ipcsimple D/MessengerActivity: msg from client: reply from service outage
Server:
04-22 02:08:07.083 21231-21231/com.dou.ipcsimple:remote2 D/MessengerService: Service onBind
msg from client:Hi, i am client.