理解Aidl中Stub和Stub.Proxy

前言
之前看Binder的时候,一直对aidl自动生成的Stub类和Stub.Proxy类感到很疑惑。为什么要创建两个类呢?他们的区别在哪呢?他们代表的意思又是什么呢?
本文尝试去解答这些问题。

AIDL的基础使用
可以看看这篇文章:http://blog.csdn.net/liuhe688/article/details/6400385
或者官网的文章:http://developer.android.com/intl/zh-cn/guide/components/aidl.html
如果没了解过aidl的请先看这两篇文章再往下看。

asInterface()返回的Stub和Stub.Proxy
我们都知道,Binder的工作机制由客户端,Binder,服务端组成的,客户端和服务端都是通过Binder来交流的。可见Binder的重要性。关于Binder的定义有很多种,本文关注的是它在代码方面的定义:Binder是Android中一个java类。aidl生成的java代码中,Stub类是继承于Binder类的,也就是说Stub实例就是Binder实例。

实例中服务端一般会实例化一个Binder对象,例如上面第一篇文章里的:

public class AIDLService extends Service {  

    private static final String TAG = "AIDLService";  

    IPerson.Stub stub = new IPerson.Stub() {  
        @Override  
        public String greet(String someone) throws RemoteException {  
            Log.i(TAG, "greet() called");  
            return "hello, " + someone;  
        }  
    };  

    @Override  
    public IBinder onBind(Intent intent) {  
        Log.i(TAG, "onBind() called");  
        return stub;  
    }  
    ...
}  

然后客户端中在Service绑定的时候可以获取到这个Stub(Binder),如:

private IPerson person;  
    private ServiceConnection conn = new ServiceConnection() {  

        @Override  
        public void onServiceConnected(ComponentName name, IBinder service) {  
            Log.i("ServiceConnection", "onServiceConnected() called");  
            person = IPerson.Stub.asInterface(service);  
        }  

        @Override  
        public void onServiceDisconnected(ComponentName name) {  
            //This is called when the connection with the service has been unexpectedly disconnected,  
            //that is, its process crashed. Because it is running in our same process, we should never see this happen.  
            Log.i("ServiceConnection", "onServiceDisconnected() called");  
        }  
    };

像上面一样,在连接Service的时候,服务端的Stub(Binder)以参数的形式传过来了–IBinder service,然后我们通过asInterface()方法获取它的实例对象。

我们从Android对aidl文件自动生成的java类中可以看到asInterface()这个接口的实现,大概的意思就是:
如果客户端和服务端在同一个进程下,那么asInterface()将返回Stub对象本身,否则返回Stub.Proxy对象。

也就是说asInterface()返回的对象有两种可能(实际上有三种,还有一种是null),Stub和Stub.Proxy。它们有什么区别呢?

  1. 如果在同一个进程下的话,那么asInterface()将返回服务端的Stub对象本身,因为此时根本不需要跨进称通信,那么直接调用Stub对象的接口就可以了,返回的实现就是服务端的Stub实现,也就是根本没有跨进程通信;

  2. 如果不是同一个进程,那么asInterface()返回是Stub.Proxy对象,该对象持有着远程的Binder引用,因为现在需要跨进程通信,所以如果调用Stub.Proxy的接口的话,那么它们都将是IPC调用,它会通过调用transact方法去与服务端通信。

以上就是两者的区别。

所以它们这个名字是什么意思呢?从字面意思看,Stub是存根,Proxy是代理,感觉两者好像差不多。而这个Stub是谁的存根呢?Proxy又是谁的代理呢?
我认为Stub是服务端实现的存根,而Proxy则是Stub的代理。
是不是很难理解?其实我自己写完都理解不能。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页