Aidl中Stub和Stub.Proxy的理解

来源:互联网 发布:linux测试端口命令 编辑:程序博客网 时间:2024/06/05 07:45

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

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;  }  ...

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
然后客户端中在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");      }  };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
像上面一样,在连接Service的时候,服务端的Stub(Binder)以参数的形式传过来了–IBinder service,然后我们通过asInterface()方法获取它的实例对象。

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

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

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

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

以上就是两者的区别。

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

转载自:http://blog.csdn.net/scnuxisan225/article/details/49970217

原创粉丝点击