Android IPC:调用了 onServiceConnected,然后是 NullPointerException
Android IPC: onServiceConnected called, followed by NullPointerException
我们的应用程序连接到通过 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;
}
};
在 onServiceConnected
回调调用期间调用 serviceConnected()
后,我们假设连接已建立并且 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
变量没有被初始化。我只看到此行为的一个潜在原因:系统传递给 onServiceConnected
的 IBinder
对象是 null
(我 100% 确信对象在 onBind()
中返回IPC 服务有效)
我在网上找不到任何关于这种情况的信息,因此我的问题是:
- 有没有人遇到过类似的行为?
- 是否存在
onServiceConnected
作为第二个参数传递 null
而不是远程 Service
返回的有效 IBinder
的情况?
感谢@pskink 的帮助,我意识到 onServiceConnected
不能用 null IBinder
调用,AIDL 的 Stub.asInterface
也不能 return null.
底线:onServiceConnected
回调中不需要空值检查。
我们的应用程序连接到通过 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;
}
};
在 onServiceConnected
回调调用期间调用 serviceConnected()
后,我们假设连接已建立并且 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
变量没有被初始化。我只看到此行为的一个潜在原因:系统传递给 onServiceConnected
的 IBinder
对象是 null
(我 100% 确信对象在 onBind()
中返回IPC 服务有效)
我在网上找不到任何关于这种情况的信息,因此我的问题是:
- 有没有人遇到过类似的行为?
- 是否存在
onServiceConnected
作为第二个参数传递null
而不是远程Service
返回的有效IBinder
的情况?
感谢@pskink 的帮助,我意识到 onServiceConnected
不能用 null IBinder
调用,AIDL 的 Stub.asInterface
也不能 return null.
底线:onServiceConnected
回调中不需要空值检查。