Android IPC bindService传递Messenger

IPC for Android 系列:
1、Android IPC
2、Serializable、Parcelable、Binder的使用、理解
3、本文Android IPC bindService传递Messenger
4、结合PMS源码讲解AIDLPackageManagerService服务框架

Messenger:信使,可在不同进程间传递Message;轻量级IPC方案,底层实现AIDL;

服务端

第一步:创建一个Service做服务端

public class MessengerService extends Service {

    private final Messenger mMessenger = new Messenger(new MessengerHandler());

    public static class MessengerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case Utils.MSG_FROM_CLIENT:
                    Log.d("yink","client msg = " + msg.getData().getString("msg"));

                    Messenger client = msg.replyTo;
                    Message replayMessage = Message.obtain(null,Utils.MSG_FROM_SERVICE);
                    Bundle data = new Bundle();
                    data.putString("replay","Msg is arrived!");
                    replayMessage.setData(data);
                    try {
                        if(client != null) {
                            client.send(replayMessage);
                        } else {
                            Log.d("yink","don't replay");
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mMessenger.getBinder();
    }
}

1、定义了一个Messenger,一个Handler;
2、在onBind中返回mMessenger的Ibinder;
3、当客户端发送Messenger发送一个Message消息过来的时候,MessengerHandler就会接收这个消息;

客户端

第二步:绑定服务端bindService

public class MessengerAcitvity extends Activity {

    private static Messenger mMesenger;
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mMesenger = new Messenger(service);
            Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
            Bundle data = new Bundle();
            data.putString("msg","hello this is client");
            msg.setData(data);
            msg.replyTo = mGetReplayMessenger;
            try {
                mMesenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    private static Messenger mGetReplayMessenger = new Messenger(new MessengerHandler());
    private static class MessengerHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case Utils.MSG_FROM_SERVICE:
                    Log.d("yink","service msg = " + msg.getData().getString("replay"));
                    secondMsgTest();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger_acitvity);

        Intent intent = new Intent(this,MessengerService.class);
        bindService(intent,mConnection, Context.BIND_AUTO_CREATE);
    }

    public static void secondMsgTest() {
        Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
        Bundle data = new Bundle();
        data.putString("msg","client second msg");
        msg.setData(data);
        try {
            if(mMesenger != null) {
                mMesenger.send(msg);
            }
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        unbindService(mConnection);
        super.onDestroy();
    }
}

1、先看onCreate的bindService,绑定操作;
2、mConnection中onServiceConnected,先得到一个Messenger,看Messenger的构造函数就明白了,标准的binder(不明白的读者可以阅读系列文章的第二篇)

public Messenger(IBinder target) {
    mTarget = IMessenger.Stub.asInterface(target);
}

然后是封装一条Message消息

Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
Bundle data = new Bundle();
data.putString("msg","hello this is client");
msg.setData(data);
msg.replyTo = mGetReplayMessenger; //注意此句是把mGetReplayMessenger传递给服务端,当服务端发送消息时,通过mGetReplayMessenger创建的handler接收消息

最后mMesenger.send(msg);向服务端发送消息;

接下来我们看客户端和服务端怎么来回交互:

客户端发送完消息后,我们回到服务端代码handleMessage:
1、log打印出接收到的消息

05-11 10:20:07.880 31158 31158 D yink    : client msg = hello this is client

2、得到客户端传过来的Messenger

Messenger client = msg.replyTo;

3、封装好一条Message后,再发送回客户端

client.send(replayMessage);

回到客户端代码:
1、mGetReplayMessenger的handleMessage中log打印接收到的消息:

05-11 10:20:07.881 31115 31115 D yink    : service msg = Msg is arrived!

2、调用secondMsgTest,发送第二条消息给服务端
这里附加说明一下,在onCreate绑定service后,客户端就单独执行了,若直接发送secondMsgTest,是不会发送的,这个时候mMesenger还是为空;

public static void secondMsgTest() {
    Message msg = Message.obtain(null,Utils.MSG_FROM_CLIENT);
    Bundle data = new Bundle();
    data.putString("msg","client second msg");
    msg.setData(data);
    try {
        if(mMesenger != null) {
            mMesenger.send(msg);
        }
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

贴出所有log如下:

05-11 10:20:07.880 31158 31158 D yink    : client msg = hello this is client
05-11 10:20:07.881 31115 31115 D yink    : service msg = Msg is arrived!
05-11 10:20:07.882 31158 31158 D yink    : client msg = client second msg
05-11 10:20:07.882 31158 31158 D yink    : don't replay

你可能感兴趣的:(Android IPC bindService传递Messenger)