Android Cross-Process Communication-IPC Preliminary Exploration (2) - Using Messenger

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.


  1. How Messenger works:
    write picture description here

  2. 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.
  3. Coding implementation:

    1. server process

      • We create a service MessengerServiceto handle client connection requests and specify a new process name for this Servie.
      • Create a MessengerServiceHandler and create a Messenger object from it.
      • Return the Binder object of the lower level of this Messenger in MessengerServicethe 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();
            }
        }
    2. 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();
            }
        }
    3. The complete code can be found here:

      Github-IPCSimple

    4. 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:
        Select debug 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.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325611804&siteId=291194637