此篇来Mark一下Android中的aidl接口调用中的问题:
aidl接口中的会通过回调返回一个自定义的IBinder实例;
通常我们调用时会先bindService,然后要等...之所以要等,是因为bindService之后,ServiceConnection接口中的回调onServiceConnected,总是会延时几百毫秒才会被调用到,所以,调用完bindService之后立即调用返回的IBinder实例是不行的;
有些资料中加了一个判断:binder != null,因为这个回调的延时,这个判断未必准确,为空不一定说明没有连上,同样的不为空也不一定说明连接任然有效!(因为onServiceDisconnected回调同样也会有延时)。
另外,不要在主线程中以同步的方式连接并调用IBinder实例中的方法!
这里面有很多原因,因为方法中有耗时工作导致主线程ANR只是其中一个原因;除此之外,如果你想在一个按钮事件中(或者主线程消息队列的同一消息中)同时连接(bindService)并调用IBinder实例中的方法,这是不可能成功的!(即使你注意到了连接之后有延时,并且你等待了几秒),这是因为aidl接口的回调(onServiceConnected与onServiceDisconnected)一定是在主线程中执行的,回调操作被丢到主线程的消息队列中,如果你连接之后不返回,主线程就一直被你当前的消息或者事件占用着,回调就进不来,你就不要希望能调用到IBinder实例中的任何方法,因为此时IBinder实例一直是null,你必须在连接和调用IBinder实例中的方法之间释放(不占用)主线程,让消息循环能处理消息队列中接下来的消息(回调就是其中之一)!
要避免以上这个问题,你就必须分两个事件处理,或者干脆不在主线程中连接Service。