【问题标题】:service binder receives custom aidl callback interface as null服务绑定器接收自定义aidl回调接口为null
【发布时间】:2015-02-10 07:15:37
【问题描述】:

我在绑定服务中传递自定义 AIDL 回调接口。服务绑定器将其作为 null 接收。

服务和客户端在不同的进程中运行。用于绑定服务和回调存根适配器aidl 和类的请求、响应、服务、绑定器、实用程序类位于服务和客户端类(在单独的应用程序中)都使用的android 库项目中。

这里是相关代码(减去导入)。 (编译正常,没有运行时异常)

// service callback IResponseReceiver.aidl
oneway interface IResponseReceiver {
    void onReceiveResponseA(in int statusCode, in ResponseA response);
    void onReceiveResponseB(in int statusCode, in ResponseB response);
}

// service aidl
oneway interface IService {
    void executeA(in RequestA request, in IResponseReceiver receiver);
    void executeB(in RequestB request, in IResponseReceiver receiver);
}

// service binder
public class ServiceImpl extends IService.Stub {
    private ExecutorService mExecutor;

    @Override
    public void executeA(RequestA request, IResponseReceiver receiver) throws RemoteException {
        mExecutor.execute(handle(request, receiver)); // receiver == null here
    }

    @Override
    public void executeB(RequestB request, IResponseReceiver receiver) throws RemoteException {
        mExecutor.execute(handle(request, receiver)); // receiver == null here
    }
}

// service callback adapter class
class ResponseReceiver extends IResponseReceiver.Stub {
    @Override
    public void onReceiveResponseA(int statusCode, ResponseA response)
        throws RemoteException {
    }

    @Override
    public void onReceiveResponseB(int statusCode, ResponseB response)
        throws RemoteException {
    }
}

// service callback class in client
class ClientResponseReceiver extends ResponseReceiver {
    @Override
    public void onReceiveResponseB(int statusCode, ResponseB response)
        throws RemoteException {
        // do something
        }
}

// utility class for calling bound service method
class ServiceChannel implements ServiceConnection {
    private IService mService;

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mService = IService.Stub.asInterface(service);
    }

    void execute(RequestA request, ResponseReceiver receiver) {
        mService.executeA(request, receiver); // receiver != null here
    }
}

调用 startService() 的活动也会为客户端应用调用 startActivity(FLAG_ACTIVITY_NEW_TASK)。客户端应用绑定服务并调用 IService.executeA()。

我做错了什么?没有堆栈跟踪显示任何错误。

提前致谢。

【问题讨论】:

  • 什么是空?更具体...
  • 接收者为空。
  • 我想我们需要看看你们的服务。 ServiceChannel.execute 的调用在哪里?
  • 客户端应用正在调用 channel.execute(requestA, new ClientResponseReceiver());
  • // 这是我导出的服务 public class MyService extends Service { private IBinder mImpl = new ServiceImpl(); @Override public IBinder onBind(Intent intent) { return mImpl; } }

标签: android service callback aidl


【解决方案1】:

呃。抱歉,拖了这么久。

IService 中方法的 AIDL 定义只接受一个参数。第二个参数没有通过 Binder。你需要:

interface IService {
    void executeA(in RequestA request, in IResponseReceiver receiver);
    void executeB(in RequestB request, in IResponseReceiver receiver);
}

【讨论】:

  • 对这个错字非常抱歉。我的界面看起来与您定义的完全一样。我打错了aidl。谢谢老兄。
  • 抱歉,我的评论看起来很混乱。我仍然有这个问题。错字出现在堆栈溢出帖子中,而不是代码中。
【解决方案2】:

服务从 App-1 启动。 App-1 还使用 FLAG_ACTIVITY_NEW_TASK 启动 App-2。 App-2 尝试绑定到服务。

看起来 FLAG_ACTIVITY_NEW_TASK 是问题所在。

【讨论】:

    【解决方案3】:

    在 android AIDL 中,您不能使用普通的 java 对象作为回调或接收器,因为它们处于不同的进程中。 考虑使用 RemoteCallbackList;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 1970-01-01
      • 2012-09-10
      • 2018-03-15
      • 2020-10-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多