理解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。它們有什麼區別呢?
如果在同一個程序下的話,那麼asInterface()將返回服務端的Stub物件本身,因為此時根本不需要跨進稱通訊,那麼直接呼叫Stub物件的介面就可以了,返回的實現就是服務端的Stub實現,也就是根本沒有跨程序通訊;
如果不是同一個程序,那麼asInterface()返回是Stub.Proxy物件,該物件持有著遠端的Binder引用,因為現在需要跨程序通訊,所以如果呼叫Stub.Proxy的介面的話,那麼它們都將是IPC呼叫,它會通過呼叫transact方法去與服務端通訊。
以上就是兩者的區別。
所以它們這個名字是什麼意思呢?從字面意思看,Stub是存根,Proxy是代理,感覺兩者好像差不多。而這個Stub是誰的存根呢?Proxy又是誰的代理呢?
我認為Stub是服務端實現的存根,而Proxy則是Stub的代理。
是不是很難理解?其實我自己寫完都理解不能。