如何创建一个Android本地服务并使用Binder进行通信?

14

我的基本任务是在Android中创建一个本地服务,然后编写一个简单的本地程序来测试它。假设我想编写一个简单的服务,用于返回两个整数的和。我必须使用绑定器从程序中访问它,我已经尝试了Google搜索,但我找不到精确的例子。我需要知道如何创建本地服务并在程序中查找它,如果需要还要在Java中。

3个回答

13

如果您正在使用NDK创建普通的Android应用程序,则无法使用Binder,因为它不是NDK API的一部分。

请参阅NDK docs/STABLE-APIS.html获取稳定API的完整列表,并查看此线程以获取David Turner(NDK维护者)发表的明确评论,即Binder不是受支持的API。

https://groups.google.com/forum/?fromgroups=#!topic/android-ndk/1QmVRrNckfM

以下是您的选项:

  • 在本地代码中使用其他形式的IPC - 例如UNIX域套接字
  • 使用Android SDK的正常Service和AIDL设施在Java中执行。如果您希望将其与本地代码结合使用,则可以使用JNI从本地代码调用Java。
  • (不建议)从Android开源项目中复制相关库和头文件;构建到您的NDK项目中;并使用API。但这不是官方支持的,而且极有可能在未来的版本中破坏您的应用程序,因为Google没有义务在这些库中保持兼容性(也经常如此)。这也非常困难,因为您需要找到某种方式注册服务,以便客户端可以找到它。

12
我找到的解决方案是使用本地Binder并使用
defaultServiceManager()->addService(
        String16("TestService"),new CalcService());

然后在客户端使用绑定器并使用以下内容。

sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("TestService"));

我在这里找到了如何做到这一点的示例:https://github.com/gburca/BinderDemo/blob/master/binder.cpp


我找不到用于链接的libbinder.so库文件?你是如何解决这个问题的? - TorukMakto
4
在构建AOSP时,可以使用libbinder.so库,但我认为这个库在NDK中不可用。 - VinayChoudhary99
它在Android 11上没有帮助。收到的消息是:在文件external/BinderDemo/binder.cpp的第222行,函数getDemoServ中断言失败。 - GNK

5

在学习和编码 Android NDK 后,我发现 Binder API 在 Android NDK 中不可用。即使您使用 Android 开放源代码来调用 binder api,也可能会因绑定器安全检查而获得权限被拒绝

如果我想将服务添加到系统服务中,我需要一个系统级用户组。详细的代码可以在https://github.com/qianjigui/android_system_service_example找到。它包含 C 和 Java 级别的客户端和服务端,但您需要系统权限。


关于权限,如果您的Android版本使用SELinux,这可能会有所帮助:https://source.android.com/security/selinux/implement 记得根据您的版本使用/dev/binder或/dev/vndbinder。 - Santiago Villafuerte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接