当前位置:   article > 正文

【Android】进程通信IPC——Messenger_fstack ipc message error

fstack ipc message error

Messenger可以说是信使,用于不同进程间通信。Messenger是轻量级的IPC,内部是使用了AIDL。

服务端

创建Service,使用Handler参数的Messenger构造方法,具体的数据获取等操作放在Handler#handleMessage()方法中。

public class MessengerService extends Service {
    private static final String TAG = "MessengerService";
    Messenger messenger = new Messenger(new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 1) {
                String message = (String) msg.getData().get("message");
                Log.i(TAG, "服务端收到消息:" + message);
                Message replyMessage = Message.obtain();
                replyMessage.what = 2;
                Bundle bundle = new Bundle();
                bundle.putString("message","服务端已收到客户端消息,内容如下---"+message);
                replyMessage.setData(bundle);
                try {
                    msg.replyTo.send(replyMessage);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    });

    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

客户端

客户端使用bindService方式关联启动服务,在ServiceConnection#onServiceConnected回调中获取服务端Messenger。

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //服务端Messenger
            serviceMessenger = new Messenger(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            serviceMessenger = null;
        }
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

向服务端Messenger发送消息,并设置回复处理的客户端Messenger。

    Message message = Message.obtain();
    message.what = 1;
    Bundle bundle = new Bundle();
    bundle.putString("message", String.format("客户端%s发送信息", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())));
    message.setData(bundle);
    //设置回复处理的Messenger
    message.replyTo = clientMessenger;
    if (serviceMessenger != null) {
        try {
            serviceMessenger.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

源码分析

Messenger的构造函数,在创建客户端和服务端Messenger的时候有用到。

    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
  • 1
  • 2
  • 3

getIMessenger()的源码可以看到就是一个继承了IMessenger.Stub的类,

    final IMessenger getIMessenger() {
        synchronized (mQueue) {
            if (mMessenger != null) {
                return mMessenger;
            }
            mMessenger = new MessengerImpl();
            return mMessenger;
        }
    }

    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            msg.sendingUid = Binder.getCallingUid();
            Handler.this.sendMessage(msg);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

IMessenger的AIDL如下,里面提供了一个send方法

// /frameworks/base/core/java/android/os/IMessenger.aidl
package android.os;

import android.os.Message;

/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

IBinder为参数的构造函数和AIDL的很像

    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }
  • 1
  • 2
  • 3

Messenger和AIDL区别

  1. 从源码就能看出Messenger就是对AIDL做了个封装,但Messenger只能传递数据,无法调用方法;
  2. Messenger是以串行方式处理客户端发送的消息,AIDL支持并发处理客户端消息;
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/122548
推荐阅读
相关标签
  

闽ICP备14008679号