IPC(七)--Messenger源码分析

2019-02-21  本文已影响0人  azu_test

移步Android跨进程通信IPC

简介

Messenger的底层实现是AIDL,所以一些AIDL相关的内容此处不再赘述。

代码分析

1. Messenger内主要代码分析
public final class Messenger implements Parcelable {
    //持有IMessenger对象,可能是IMessenger#Stub,也可能是IMessenger#Proxy
    private final IMessenger mTarget;
    //构造方法,根据Handler内持有的IMessenger#Stub构造
    public Messenger(Handler target) {
        mTarget = target.getIMessenger();
    }
    ////构造方法,根据Binder,此时会根据不同情况产生Proxy或者Stub
    public Messenger(IBinder target) {
        mTarget = IMessenger.Stub.asInterface(target);
    }
    //发送消息
    public void send(Message message) throws RemoteException {
        mTarget.send(message);
    }
    //获取Binder对象
    public IBinder getBinder() {
        return mTarget.asBinder();
    }
    ...
}
  1. 由上面代码可知,Messenger就是对IMessenger的一层简单封装,里面持有的IMessenger对象在服务端内是IMessenger#Stub对象。
    根据AIDL内的AIDL.Stub.asInterface()的分析可知
  2. 如果客户端个服务端不在一个进程内,则客户端内的Messenger. IMessenger为IMessenger#Proxy对象
  3. 如果客户端个服务端在一个进程内,则客户端内的Messenger. IMessenger为IMessenger#Stub对象
2. Handler内Messenger的相关代码
    IMessenger mMessenger;
    //在Messenger的构造方法内使用
    final IMessenger getIMessenger() {
        synchronized (mQueue) {
            if (mMessenger != null) {
                return mMessenger;
            }
            //实例化一个IMessenger#Stub对象,并实现send()方法
            mMessenger = new MessengerImpl();
            return mMessenger;
        }
    }

获取Handler内的IMessenger #Stub对象,如不存在则创建一个

    //对IMessenger.Stub的实现,并实现了send对象,通过Handler本身作为消息发送处理
    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            msg.sendingUid = Binder.getCallingUid();
            Handler.this.sendMessage(msg);
        }
    }

实现了send对象,把客户端发送过来的Message通过Handler本身作为消息发送处理,进而服务端可以接收并处理,由此可知Messenger为串行通信,所以不能很好的处理高并发的情形。

执行流程

Messenger和AIDL的原理是基本是完全一致的。
服务端的不同点在于实现方式和方法处理代码分析中也做了分析。
客户端的不同点仅仅是将获取IMessenger的aidl对象封装在了Messenger中。

上一篇 下一篇

猜你喜欢

热点阅读