Androidにおけるプロセス間通信方式の使用Messenger


サービス側MessengerServiceのprocessプロパティは、MainActivityと同じプロセスではないプロセスを指定します.
        <service  android:name="com.example.activity.MessengerService" android:process="com.example.activity.remote" >
        </service>

MessengerServiceでは、バインドサービスが返すIBinderオブジェクトとして最下位のbinderを使用するMessengerを作成します.
    private final Messenger messenger = new Messenger(new messengerHandler());
    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }

MessengerHandlerは、クライアントがサービス側にMessengerを介して送信するMessageを処理するために使用される.
private class messengerHandler extends Handler{

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            System.out.println(msg.getData().getString("msg"));
        }

    }

クライアントMainActivityでサービスをバインドします.
                Intent intent = new Intent();
                intent.setClass(MainActivity.this, MessengerService.class);
                bindService(intent, conn, Context.BIND_AUTO_CREATE);

サービスをバインドするには、サービスが返すIBinderオブジェクトをバインドしてMessengerを作成し、クライアントが送信する情報をサービス側に送信するサービス接続が必要です.
private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Messenger messenger = new Messenger(service);
            Message msg = Message.obtain();
            Bundle data = new Bundle();
            data.putString("msg", "hello!!!");
            msg.setData(data);
            try {
                messenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };

このとき、サービス側はmessengerHandlerを介してクライアントから送信されたメッセージを受信し、プロセス間の通信を完了することができる.もちろん、サービス側はクライアントにメッセージを返信することもできます.クライアントにもMessengerを作成し、hanlderによってサービス側から送信されたメッセージを処理できます.
private Messenger mainMessenger = new Messenger(new MessengerHandler());
private class MessengerHandler extends Handler{

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            System.out.println(msg.getData().getString("reply"));
        }

    }

もちろんクライアントのmainMessengerをサービス側に渡し,サービス側はmainMessengerを介してクライアントにメッセージを送る必要がある.ここではMessageのreplyTo属性伝達を用いる.
msg.replyTo = mainMessenger;

サービス側は、クライアントから渡されたMessengerを介してクライアントにメッセージを返すことができます.
            Messenger client = msg.replyTo;
            Bundle bundle = new Bundle();
            Message reply = Message.obtain();
            bundle.putString("reply", "hello yeah!");
            reply.setData(bundle);
            try {
                client.send(reply);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

この場合、クライアントはmainMessengerを介してサービス側から返信されたメッセージを取得できます.
Messenger通信を使用すると、メッセージが1つ1つ処理されているため、高同時性をうまく処理できません.メッセージはMessageを介して転送されるため、Bundleデータ型のみがサポートされます.この方式は、低同時のインスタント通信において使用することができる.