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 变量没有被初始化。我只看到此行为的一个潜在原因:系统传递给 onServiceConnectedIBinder 对象是 null(我 100% 确信对象在 onBind() 中返回IPC 服务有效)

我在网上找不到任何关于这种情况的信息,因此我的问题是:

  1. 有没有人遇到过类似的行为?
  2. 是否存在 onServiceConnected 作为第二个参数传递 null 而不是远程 Service 返回的有效 IBinder 的情况?

感谢@pskink 的帮助,我意识到 onServiceConnected 不能用 null IBinder 调用,AIDL 的 Stub.asInterface 也不能 return null.

底线:onServiceConnected 回调中不需要空值检查。