我们的应用程序连接到通过AIDL接口公开的IPC Service
。到目前为止,一切工作正常,但突然我们发现在调用onServiceConnected
回调后立即抛出NullPointerException。
我们通过以下方式绑定服务:
boolean isServiceBound = context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
然后我们确保服务绑定成功并且后台线程等待调用onServiceConnected
回调:
private ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder binder) {
Log.d(TAG, "converting Binder into IAidlService");
aidlService = IAidlService.Stub.asInterface(binder);
serviceConnected(); // this call releases background thread that waits for connection to be established
}
public void onServiceDisconnected(ComponentName className) {
Log.d(TAG, "IAidlService disconnected unexpectedly");
aidlService = null;
}
};
在调用serviceConnected()
回调期间调用onServiceConnected
后,我们假设已建立连接并初始化aidlService
变量(除非onServiceDisconnected
之后被调用,但它不是这里的情况。)
正如我所说,这个方案在一段时间内运行良好,但突然我们在onServiceConnected
之后遇到了NullPointerException。 Logcat输出:
01-21 14:06:32.717 22651-22651/com.xxx.xxx D/LocalService: converting Binder into IAidlService
01-21 14:06:32.721 22651-9574/com.xxx.xxx E/AndroidRuntime: FATAL EXCEPTION: IntentService[LocalService]
01-21 14:06:32.721 22651-9574/com.xxx.xxx E/AndroidRuntime: Process: com.xxx.xxx, PID: 22651
01-21 14:06:32.721 22651-9574/com.xxx.xxx E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke interface method 'void com.yyy.yyy.IAidlService.someMethod(android.os.Bundle)' on a null object reference
如您所见,在主线程上调用aidlService
后,后台线程中使用了onServiceConnected
。我99.9%确信这里没有多线程问题,并且让后台线程等到serviceConnected()
被调用的逻辑工作正常(并且logcat中看到的4ms延迟支持这种说法)。
我们无法重现这种行为。
因此,我们知道调用onServiceConnected
,但aidlService
变量未初始化。我发现此行为只有一个可能的原因:系统传递给IBinder
的{{1}}对象为onServiceConnected
(我对100 null
中返回的对象有100%的信心IPC服务有效)
我无法在网上找到有关此方案的任何信息,因此我的问题是:
onBind()
将onServiceConnected
作为第二个参数而不是远程null
返回的有效IBinder
?答案 0 :(得分:1)
感谢@pskink的帮助,我意识到onServiceConnected
不能用null IBinder
调用,AIDL的Stub.asInterface
也不能返回null。
底线:onServiceConnected
回调中无需进行空检查。