首先当客户端BindService的时候,服务器端会先执行onCreate方法,在onCreate中执行了添加Book信息的操作,接着继续执行onBind,它返回一个Binder对象,这个对象的实现是通过IBookManager.Stub实现的,由此可知这个Stub就是一个Binder,当然看代码也可以看得出:public static abstract class Stub extends android.os.Binder implements com.games.lwp.aidltest.IBookManager,继承自Binder,自然自身就会是一个Binder,然后在客户端的ServiceConnection中就可以通过IBookManager.Stub.asInterface(service)得到aidl接口,这个service就是服务器在onBind中返回的IBinder,然后就能通过这个接口调用服务器端的方法,实现通信。到这里我们可以看出,客户端和服务器端的通信都是通过IBookManager.aidl生成的IBookManager.class接口进行操作的。其中我有一个疑惑得地方就是,虽然IBookManager.Stub类实现了IBookManager接口,但是它并没有自己实现IBookManager接口中的方法,而是通过proxy实现,当服务器端调用IBookManager.Stub方法,那么它就要实现接口的两个方法,当客户端调用调用IBookManager.Stub.asInterface(Binder),此时就会在asInterface里判断客户端和服务器端是否位于一个进程(queryLocalInterface),如果是则直接返回服务器端的aidl接口,通过这个接口调用服务器端实现的这两个方法,如果不是,则返回代理类对象proxy,通过这个对象即可调用远程服务器方法。我们可以看下这个方法queryLocalInterface:
/**
* Attempt to retrieve a local implementation of an interface
* for this Binder object. If null is returned, you will need
* to instantiate a proxy class to marshall calls through
* the transact() method.
*/
public IInterface queryLocalInterface(String descriptor);
为这个Binder对象尝试取出一个本地接口的实现,如果没有则需要proxy实例来通过transact来安排具体的调用方法。这个逻辑也就会在Stub的onTransact去实现。
网友评论