Android使用Messenger实现进程间通信

Messenger是一种轻量级的IPC方案,在进程间传送Message对象,Message中可以传送Bundle对象,Bundle中可以传送我们实现了Parcelable接口的对象。使用Messenger不会出现并发读写问题,因为Messenger是以串行方式工作的,所以如果有大量的请求,不适合使用Messenger。

Messenger有两个构造方法:

 //关联一个Handler
 public Messenger(Handler target) 
 //关联一个IBinder
 public Messenger(IBinder target)

核心思路:

1.客户端与服务器都要有自己的Messenger并且关联一个Handler

2.服务端:将mServiceMessenger通过getBinder将IBinder传递给客户端

3.客户端:通过 public Messenger(IBinder target)构造方法获得服务器的mServiceMessenger,使用mServiceMessenger.send给服务器发送消息,并且在msg中把客户端的mClientMessenger带到服务器

4.服务端:服务器在Handler中接收到msg并且拿到客户端的mClientMessenger,使用mClientMessenger.send给客户端发送消息

这里写图片描述

客户端代码:

public class MainActivity extends Activity {
    private static final int MSG_FROM_CLIENT = 0;
    private static final int MSG_FROM_SERVICE = 1;
    private ServiceConnection conn;
    private Messenger mServiceMessenger;
    private Button mButton;
    //mClientHandler
    private Handler mClientHandler = new Handler(){
        public void handleMessage(Message msgFromService) {
            switch (msgFromService.what) {
            case MSG_FROM_SERVICE:
                Log.i("zhangqi", "客户端:"+msgFromService.getData().getString("service_msg"));
                break;
            }
        };
    };
    //mClientMessenger
    private Messenger mClientMessenger = new Messenger(mClientHandler);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton = (Button) findViewById(R.id.button);
        Intent intent = new Intent(this,MyService.class);
        conn = new ServiceConnection() {



            @Override
            public void onServiceDisconnected(ComponentName name) {

            }

            @Override
            public void onServiceConnected(ComponentName name, IBinder iBinder) {
                //拿到服务器传给客户端的IBinder,通过new Messenger(service)拿到mServiceMessenger
                mServiceMessenger = new Messenger(iBinder);
                //Messenger传递的是Message,实例化一个Message
                Message msgFromClient = Message.obtain(null, MSG_FROM_CLIENT);
                //Message传递的是Bundle
                Bundle bundle = new Bundle();
                //发送一个String类型的数据
                bundle.putString("client_msg", "这里是客户端,呼叫服务器");
                msgFromClient.setData(bundle);
                //一定不要忘了将mClientMessenger带到服务器去
                msgFromClient.replyTo = mClientMessenger;
                try {
                    //调用mServiceMessenger.send将消息发送的服务器
                    mServiceMessenger.send(msgFromClient);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        };
        //绑定Service
        bindService(intent, conn, BIND_AUTO_CREATE);

        //点击按钮发送客户端请求
        mButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //由于在onServiceConnected中我们已经拿到了mServiceMessenger了,再发送消息的时候
                //直接新建Message对象就可以了,最后调用mServiceMessenger将消息发送给服务器
                Message msgFromClient = Message.obtain(null,MSG_FROM_CLIENT);
                Bundle bundle = new Bundle();
                bundle.putString("client_msg", "客户端发起一次请求");
                msgFromClient.setData(bundle);
                msgFromClient.replyTo = mClientMessenger;
                try {
                    mServiceMessenger.send(msgFromClient);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解绑Service
        unbindService(conn);
        conn = null;
    }

}

服务端代码:

public class MyService extends Service{
    private static final int MSG_FROM_CLIENT = 0;
    private static final int MSG_FROM_SERVICE = 1;
    // mServiceHandler
    private Handler mServiceHandler = new Handler(){
        public void handleMessage(android.os.Message msgFromClient) {
            switch (msgFromClient.what) {
            case MSG_FROM_CLIENT:
                //拿到客户端发来的消息
                Log.i("zhangqi", "服务器:"+msgFromClient.getData().getString("client_msg"));
                //拿到客户端的mClientMessenger
                Messenger mClientMessenger = msgFromClient.replyTo;
                //Messenger传递的是Message,所以新建一个Message实例
                Message msgFromService = Message.obtain(null,MSG_FROM_SERVICE);
                //Message传递的是Bundle
                Bundle bundle = new Bundle();
                //发送一个String类型的数据
                bundle.putString("service_msg", "这里是服务器,收到客户端请求");
                msgFromService.setData(bundle);
                try {
                    //调用mClientMessenger.send将消息发送给客户端
                    mClientMessenger.send(msgFromService);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            }
        };
    };
    // mServiceMessenger关联mServiceHandler
    private Messenger mServiceMessenger = new Messenger(mServiceHandler);

    @Override
    public IBinder onBind(Intent intent) {
        //将IBinder传给客户端,客户端通过new Messenger(IBinder)拿到mServiceMessenger;
        return mServiceMessenger.getBinder();
    }

}

将服务端Service运行在单独的进程

在AndroidManifest.xml中注册Service并且指定android:process=”com.zhangqi.remote” 这样服务端Service就会运行在com.zhangqi.remote进程上,客户端运行在以包名命名的进程上
这里写图片描述

客户端发送一次请求,客户端就会回应:
这里写图片描述

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值