Android IPC进程间通信(二)Messenger

Messenger实现进程间低并发即时通信

Messenger是一种轻量级的IPC,底层实现是AIDL,即可认为Binder。通过在Message中携带Bundle进而实现进程之间传递数据。由于Messenger一次只能处理一个请求,因此服务端们不用考虑线程同步问题。
一,我们在服务端创建一个Handler用于接受来自客户端消息,并以此Handler创建Messenger,我们将这个Messenger的Binder对象通过onBinde( )方法返回给客户端;在客户端链接服务的onServiceConnected( )方法中取得Binder对象,转化为Messenger,即可发送消息给服务端。
二,我们在客户端创建一个Handler用于接受来自服务端的消息,同样需要以此Handler创建一个Messenger并将它返回给服务端用于发送消息,怎么返回的呢?在客户端链接服务的onServiceConnected( )方法中,当客户端向服务端发送消息时携带上刚刚创建的Messenger对象,message.replyTo = 刚刚创建的Messenger对象,而在服务端的Handler中我们可以从msg中取出来自客户端的消息和Messenger对象,Messenger reply = msg.replyTo;以此向客户端发送消息。
三,优点:功能一般,支持一对多串行通信,支持实时通信
缺点:不能很好处理高并发,不支持远程RPC,只能传输Bundle支持的数据类型。
适用场景:低并发一对多即时通信,无RPC请求,或者无需返回结果的RPC请求。
1.服务端

public class MessengerService extends Service {

    public static final int SERVICE_REPLY_WHAT = 100;
    public static final String SERVICE_REPLY_KEY = "service_reply_key";
	//将此Messenger对象传递给客户端,以此向服务端发送消息
    private Messenger mMessenger = new Messenger(new ServiceHandler());

    public MessengerService() {
    }

    private class ServiceHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                //收到来自客户端的指令并进行回复
                case MainActivity.MAIN_SEND_WHAT:
                    String msgStr = msg.getData().getString(MainActivity.MAIN_SEND_KEY);
                    Toast.makeText(MessengerService.this, msgStr, Toast.LENGTH_SHORT).show();
                    //取出来自客户端的Messemger对象,以此想客户端发送消息
                    Messenger reply = msg.replyTo;
                    Message message = Message.obtain(null, SERVICE_REPLY_WHAT);
                    Bundle bundle = new Bundle();
                    bundle.putString(SERVICE_REPLY_KEY, "收到来自客户端消息,服务端很高兴,这是回信。");
                    message.setData(bundle);
                    try {
                        reply.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
   		//将服务端Handler构造的Messenger的Binger对象传送给客户端
        return mMessenger.getBinder();
    }
}

2.客户端

public class MainActivity extends AppCompatActivity {

    public static final int MAIN_SEND_WHAT = 101;
    public static final String  MAIN_SEND_KEY = "main_send_key";
    //用来自service的IBinder对象构造Messenger,向Service端发送消息
    private Messenger mMessenger;
    //以客户端Handler构造Messenger并传递给服务端,服务端以此向客户端发送消息
    private Messenger mSendMessenger = new Messenger(new mainHandler());

    private class mainHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                //收到来自服务端的回信
                case MessengerService.SERVICE_REPLY_WHAT:
                    String msgStr = msg.getData().getString(MessengerService.SERVICE_REPLY_KEY);
                    Toast.makeText(MainActivity.this, msgStr, Toast.LENGTH_SHORT).show();
                default:
                    super.handleMessage(msg);
                    break;
            }

        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(this,MessengerService.class);
        //绑定服务
        bindService(intent,mConnection,BIND_AUTO_CREATE);
    }
	//服务连接
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder Binder) {
            //取出来自服务端的Binder对象构建Messenger,以此向服务端发送消息
            mMessenger = new Messenger(Binder);
            Message message = Message.obtain(null,MAIN_SEND_WHAT);
            Bundle bundle = new Bundle();
            bundle.putString(MAIN_SEND_KEY,"你好Service,这是来自客户端的问候。");
            message.setData(bundle);
            //将客户端Handler构造的Messenger传给服务端,服务端以此Messenger向客户端发送消息
            message.replyTo = mSendMessenger;
            try {
                mMessenger.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };
}

猜你喜欢

转载自blog.csdn.net/qq_39507260/article/details/83592066