Android跨进程通信-IPC初探(二) - 使用Messenger

IPC初探(二)


本文将会介绍Messenger通信。

Mesenger是一种轻量级的IPC方案。它通过传递Message来实现数据的进程间传递。

它的底层实现是AIDL。


  1. Messenger工作原理:
    这里写图片描述

  2. 需求描述:

    • C端向S端跨进程发送msg,并封装一个bundle数据对象
    • S接收msg,读取bundler数据,并向C端返回一条新的msg,并封装一个新的bundlB数据对象。
  3. 编码实现:

    1. 服务端进程

      • 我们创建一个服务 MessengerService 来处理客户端的连接请求,并为这个Servie指定新的进程名。
      • MessengerService 创建一个Handler,并通过它创建一个Messenger对象。
      • MessengerServiceonBind 方法中返回这个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();
            }
        }
    2. 客户端进程

      • 需要绑定服务端的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();
            }
        }
    3. 可以在这里获取完整的代码:

      Github-IPCSimple

    4. 关于代码的一些细节:

      • 在运行示例的时候,如果你看不到远程服务的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.

猜你喜欢

转载自blog.csdn.net/cangely/article/details/80035491