zoukankan      html  css  js  c++  java
  • 【起航计划 036】2015 起航计划 Android APIDemo的魔鬼步伐 35 App->Service->Messenger Service Messenger实现进程间通信

    前面LocalService 主要是提供同一Application中组件来使用,如果希望支持不同应用或进程使用Service。可以通过Messenger。使用Messgener可以用来支持进程间通信而无需使用AIDL。

     下面步骤说明里Messenger的使用方法:

    • 在Service中定义一个Handler来处理来自Client的请求。
    • 使用这个Handler创建一个Messenger (含有对Handler的引用).
    • Messenger创建一个IBinder对象返回给Client( onBind方法)。
    • Client 使用从Service返回的IBinder重新构造一个Messenger 对象,提供这个Messenger对象可以给Service 发送消息。
    • Service提供Handler接受来自Client的消息Message. 提供handleMessage来处理消息。

    在这种方式下,Service没有定义可以供Client直接调用的方法。而是通过”Message”来传递信息。

    本例Messenger Service 涉及到两个类 MessengerServiceActivities 和 MessengerService.

    首先看看Service的定义,在MessengerService定义了一个IncomingHandler ,用于处理来自Client的消息。

        /**
         * Handler of incoming messages from clients.
         */
        class IncomingHandler extends Handler {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_REGISTER_CLIENT:
                        mClients.add(msg.replyTo);
                        break;
                    case MSG_UNREGISTER_CLIENT:
                        mClients.remove(msg.replyTo);
                        break;
                    case MSG_SET_VALUE:
                        mValue = msg.arg1;
                        for (int i=mClients.size()-1; i>=0; i--) {
                            try {
                                mClients.get(i).send(Message.obtain(null,
                                        MSG_SET_VALUE, mValue, 0));
                            } catch (RemoteException e) {
                                // The client is dead.  Remove it from the list;
                                // we are going through the list from back to front
                                // so this is safe to do inside the loop.
                                mClients.remove(i);
                            }
                        }
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
        }

    然后使用这个IncomingHandler定义一个Messenger:

        /**
         * Target we publish for clients to send messages to IncomingHandler.
         */
        final Messenger mMessenger = new Messenger(new IncomingHandler());

    应为这种方法采用的“Bound” Service模式,onBind 需要返回一个IBind对象, 可以通过mMessenger.getBinder()返回与这个Messenger关联的IBinder对象,Client可以通过这个IBinder 对象重新构造一个Messenger对象,从而建立起与Service之间的通信链路。

        /**
         * When binding to the service, we return an interface to our messenger
         * for sending messages to the service.
         */
        @Override
        public IBinder onBind(Intent intent) {
            return mMessenger.getBinder();
        }

    再看看Client 的代码MessengerServiceActivities 在 ServiceConnection的 onServiceConnected的定义,这个方法返回MessengerService 的onBind 定义的IBinder对象:

                public void onServiceConnected(ComponentName className,
                        IBinder service) {
                    // This is called when the connection with the service has been
                    // established, giving us the service object we can use to
                    // interact with the service.  We are communicating with our
                    // service through an IDL interface, so get a client-side
                    // representation of that from the raw service object.
                    mService = new Messenger(service);
                    mCallbackText.setText("Attached.");
    
                    // We want to monitor the service for as long as we are
                    // connected to it.
                    try {
                        Message msg = Message.obtain(null,
                                MessengerService.MSG_REGISTER_CLIENT);
                        msg.replyTo = mMessenger;
                        mService.send(msg);
                        
                        // Give it some value as an example.
                        msg = Message.obtain(null,
                                MessengerService.MSG_SET_VALUE, this.hashCode(), 0);
                        mService.send(msg);
                    } catch (RemoteException e) {
                        // In this case the service has crashed before we could even
                        // do anything with it; we can count on soon being
                        // disconnected (and then reconnected if it can be restarted)
                        // so there is no need to do anything here.
                    }
                    
                    // As part of the sample, tell the user what happened.
                    Toast.makeText(Binding.this, R.string.remote_service_connected,
                            Toast.LENGTH_SHORT).show();
                }

    本例实现了Client与Service 之间的双向通信,因此在Client也定义了一个Messenger对象mMessenger,用于处理来自Service的消息。

    有了 mService对象,就可以使用send向Service发送消息,如过需要Service 返回信息,可以定义message.replyTo 对象。

  • 相关阅读:
    maven打包额外的资源文件
    阿里巴巴的程序员等级
    sql是最成功的第四代语言
    nginx的配置与应用
    浏览器的同源策略与跨域问题的解决方案
    算法:二分查找(基础)
    动态类型语言和静态类型语言
    【VS开发】单文档中往视图中加入控件
    【VS开发】使用VS2010创建MFC ActiveX工程项目
    【VS开发】使用VS2010创建MFC ActiveX工程项目
  • 原文地址:https://www.cnblogs.com/dongdong230/p/4330040.html
Copyright © 2011-2022 走看看