1. 程式人生 > >理解Aidl中Stub和Stub.Proxy

理解Aidl中Stub和Stub.Proxy

前言
之前看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; } ... }

然後客戶端中在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的代理。
是不是很難理解?其實我自己寫完都理解不能。