现在的位置: 首页 > 综合 > 正文

利用messenger实现进程通信

2013年04月17日 ⁄ 综合 ⁄ 共 3313字 ⁄ 字号 评论关闭

       通常,我们用aidl实现android上层进程间的通信, 除此之外,我们也可以用messenger来实现。 当然,

这俩者背后都是binder机制的实现,这里主要讲messenger的方式。

        参考android4.0 bluetooth的源码,BluetoothHDPActivity.java, BluetoothHDPService.java这两个文件,其中,

Activity作为 client.

    先看Server端,BuetoothHDPService.java

private class IncomingHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                // Register UI client to this service so the client can receive messages.
                case MSG_REG_CLIENT:
                    Log.d(TAG, "Activity client registered");
                    mClient = msg.replyTo;
                    break;
                // Unregister UI client from this service.
                case MSG_UNREG_CLIENT:
                    mClient = null;
                    break;
                // Register health application.
                case MSG_REG_HEALTH_APP:
                    registerApp(msg.arg1);
                    break;
                // Unregister health application.
                case MSG_UNREG_HEALTH_APP:
                    unregisterApp();
                    break;
                // Connect channel.
                case MSG_CONNECT_CHANNEL:
                    mDevice = (BluetoothDevice) msg.obj;
                    connectChannel();
                    break;
                // Disconnect channel.
                case MSG_DISCONNECT_CHANNEL:
                    mDevice = (BluetoothDevice) msg.obj;
                    disconnectChannel();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    final Messenger mMessenger = new Messenger(new IncomingHandler());

   @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    };

         在server端, 定义了一个messenger,参数是一个Handler, 可以想到的是,这个Handler 一定是给 Client 去调用的, 

并通过 onBind 方法, 返回了这个messenger的 binder对象(aidl的方式中,返回的是Server 的一个代理  finalIRemoteService.Stub mBinder=newIRemoteService.Stub()    )

         好了,我们看看,client 端, 通过bindService, 做了什么操作。

BluetoothHDPActivity.java,         

    bindService(intent, mConnection, Context.BIND_AUTO_CREATE); 
    

private ServiceConnection mConnection = new ServiceConnection() {         public void onServiceConnected(ComponentName name, IBinder service) {             mHealthServiceBound = true;             Message msg = Message.obtain(null, BluetoothHDPService.MSG_REG_CLIENT);             msg.replyTo = mMessenger;             mHealthService = new Messenger(service);\             try {                 mHealthService.send(msg);             } catch (RemoteException e) {                 Log.w(TAG, "Unable to register client to service.");                 e.printStackTrace();             }         }

        public void onServiceDisconnected(ComponentName name) {             mHealthService = null;             mHealthServiceBound = false;         }     };

      

         这里, 我们看到,onServiceConnected 里,获取了server端的 messenger, 并通过send 的方式, 实现

了向 server 里的 handler 发送消息的功能,至此, 我们了解了, 通过messenger, 实现跨进程发送消息的功能.

在这段代码里, 他send 一个消息给server端, 看代码, msg.replyTo = mMessenger, 这里, 他有带了一个

client 端的mMessager 给server端,我们看mMessenger:

   // Handles events sent by {@link HealthHDPService}.
    private Handler mIncomingHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                // Application registration complete.
                case BluetoothHDPService.STATUS_HEALTH_APP_REG:
                    mStatusMessage.setText(
                            String.format(mRes.getString(R.string.status_reg),
                            msg.arg1));
                     break; //此处省略部分代码 
                 case BluetoothHDPService.STATUS_DESTROY_CHANNEL:
                    mStatusMessage.setText(
                            String.format(mRes.getString(R.string.status_destroy_channel),
                            msg.arg1));
                    mConnectIndicator.setText(R.string.disconnected);
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    };

    private final Messenger mMessenger = new Messenger(mIncomingHandler);

这部分代码跟之前的代码一样, 功能也是一样的, 几可以将messenger对象带个server, 实现server向 client 发送消息。

        通过上述介绍,利用messeger,  可以实现在 client和server之间相互发送消息, 个人觉得, 比aidl 的方式要好用些,

也容易理解些, aidl 的方式, 本文就不做过多的讲述。

        总结:

      1. 使用Messenger方式比使用AIDL的方式,实现起来要简单很多

      2. 使用Messenger时,所有从Activity传过来的消息都会排在一个队列里,不会同时请求Service,所以是线程安全的。如果你的程序就是要多线程去访问Service,就可以用AIDL,不然最好使用Messenger的方式。

 

 

 

 

 

【上篇】
【下篇】

抱歉!评论已关闭.