3

我正在尝试实现 AIDL,但我只是不明白它是如何工作的。我的意思是对方法的调用的进展是什么?

我不明白如何通过 AIDL 从服务获取对象到我的活动。我一直在使用谷歌文档寻求指导,但我很困惑。谢谢

更新:

在服务连接中,我有这些行,其中 mCallback 是 IRemoteServiceCallback。

 public void onServiceConnected(ComponentName name, IBinder service) {
            mRemoteInterface = IRemoteInterface.Stub.asInterface(service);
            Log.v(TAG, "Interface bound.");
            try{
                mRemoteInterface.registerCallback(mCallback);
            }catch(RemoteException e){

            }
            Toast.makeText(MainActivity.this, "Remote Service Connected",
                    Toast.LENGTH_SHORT).show();
        }

这是 registerCallback,其中 mCallbacks 是

final RemoteCallbackList <IRemoteServiceCallback> mCallbacks

    = new RemoteCallbackList <IRemoteServiceCallback> ();

......

public void registerCallback(IRemoteServiceCallback callback)
                throws RemoteException {
            if(callback != null){
                mCallbacks.register(callback);
            }

        }

IRemoteServiceCallback(mCallback) 的唯一方法是:

public void valueChanged(int value) {
        mHandler.sendMessage(mHandler.obtainMessage(BUMP_MSG, value, 0));
    }

我也有一个处理程序,但我不太确定如何处理:

 private Handler mHandler = new Handler() {
    @Override public void handleMessage(Message msg) {
        switch (msg.what) {
            case BUMP_MSG:
                Log.d(TAG, "Received from service: " + msg.arg1);
                break;
            default:
                super.handleMessage(msg);
        }
    }

};

更新 2:

AIDL 步骤-据我所知-。

  1. 我从 MainActivity 调用 bindService(service,connection,flags)

  2. 在我调用 bindService 并建立连接后,会自动调用 onServiceConnected。在那里,我得到了 IBinder,然后调用 registerCallback ,它放置了一个 IRemoteServiceCallback[ 这个回调来自哪里?] 进入 RemoteCallbackList 供以后访问

现在,我注意到有两个 mHandler,一个在服务中,一个在活动中。[什么时候调用它们,它们在使用方面有什么区别]

现在,RemoteCallbackList 有了我需要的回调,我可以看到在活动类的 mHandler 中我终于能够获得我想要的对象。

4

1 回答 1

12

Android 中的跨应用服务基于 Binder,一个内核级的 IPC 系统(这是IBinder类名的来源)。当您绑定到远程服务(即应用程序之外的服务)时,它可以向您返回一个对象。但是,由于您不知道实际类型是什么(方法、字段等),因此您无法将其转换为可用类型。

这就是 AIDL 的用武之地——它是一种与语言无关的指定接口的方式——方法及其参数的集合(它看起来也很像 Java——它不是)。如果客户端和服务器都使用相同的 .aidl 文件,您可以通过生成的 Java 接口绑定到对象 - IRemoteService.Stub.asInterface(obj)。在服务方面,您只需要用某种语言实现相同的接口(框架中的一些服务是用 C++ 编写的),其余的将由 IPC 机制处理。

也就是说,除非您导出服务并希望外部应用程序能够使用它,否则您不需要使用 AIDL。如果没有,只需在您的应用程序中实现 IBinder 并onServiceConnected直接转换接收到的对象,因为您知道它的类型。

于 2013-07-26T16:31:42.630 回答