Android中IPC机制之Messenger

前言

Messenger翻译为“信使”,顾名思义,可以在不同进程中传递Message对象。Messenger是一种轻量级IPC方案,底层实现也是AIDL,只是对AIDL做了封装。Messenger的使用相对于AIDL方便多,因为Messenger是Android系统中自带的类,服务端和客户端都不用创建AIDL文件。Messenger会持有一个Handler,这个Handler用于处理接受到的信息,在服务端和客户端通过Messenger实现双方通信。

构造方法

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

明显看出使用了aidl的痕迹。

服务端进程

构建一个运行在独立进程中的服务端Service:

public class MessengerService extends Service {
    private static final String TAG = "MessagerService";

    /**
     * 处理来自客户端的消息,并用于构建Messenger
     */
    private static class MessengerHandler extends Handler {
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case MESSAGE_FROM_CLIENT:
                    Log.e(TAG, "receive message from client:" + message.getData().getString("msg"));
                       //获取客户端传递过来的Messenger,通过这个Messenger回传消息给客户端
                    Messenger client = message.replyTo;
                    //当然,回传消息还是要通过message
                       Message msg = Message.obtain(null, Constant.MESSAGE_FROM_SERVICE);
                        Bundle bundle = new Bundle();
                    bundle.putString("msg", "hello client, I have received your message!");
                    msg.setData(bundle);
                    try {
                        client.send(msg);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                     break;
                default:
                    super.handleMessage(message);
                    break;
            }
        }
    }

    /**
     * 构建Messenger对象
     */
    private final Messenger mMessenger = new Messenger(new MessengerHandler());

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //将Messenger对象的Binder返回给客户端
        return mMessenger.getBinder();
    }
}

注册service,当然要设置在不同的进程

<service
    android:name="com.kanghanbin.service.MessengerService"
    android:process=":remote" />

客户端进程



public class MessengerActivity extends AppCompatActivity {
    private static final String TAG = "MessengerActivity";

    private Messenger mService;
    /**
     * 客户端Messenger对象
     */
    private Messenger mClientMessenger = new Messenger(new MessengerHandler());
    private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.e(TAG, "ServiceConnection-->" + System.currentTimeMillis());
            //通过服务端返回的Binder创建Messenger
            mService = new Messenger(iBinder);
            //创建消息,通过Bundle传递数据
            Message message = Message.obtain(null, MESSAGE_FROM_CLIENT);
            Bundle bundle = new Bundle();
            bundle.putString("msg", "hello service,this is client");
            message.setData(bundle);
            //将客户端的Messenger对象传递给服务端
            message.replyTo = mClientMessenger;
            try {
                //向服务端发送消息
                mService.send(message);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.e(TAG, "onServiceDisconnected-->binder died");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_messenger);
        //绑定服务
        Intent intent = new Intent(this, MessengerService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        //解绑服务
        unbindService(mConnection);
        super.onDestroy();
    }
}

客户端发送信息

使用Messenger向服务端发送信息,使用的是Messenger.send(Message)方法,这个方法具体实现如下:

public void send(Message message) throws RemoteException {
    mTarget.send(message);
}

方法内部调用mTarget.send(Message)方法,在Messenger中,mTarget是在构造方法里面被赋值的。

总结

  • 使用Messager来传递Message,Message中能使用的字段只有what、arg1、arg2、Bundle和replyTo,自定义的Parcelable对象无法通过object字段来传输
  • Message中的Bundle支持多种数据类型,replyTo字段用于传输Messager对象,以便进程间相互通信
  • Messager以串行的方式处理客户端发来的消息,不适合有大量并发的请求
  • Messager方法只能传递消息,不能跨进程调用方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值