0

简介:我有一个带有 Java (JNI) 包装器的本机库 (C++)。库引擎是 cpu 密集型的,我们不希望同时运行多个链接此库的应用程序,并且库引擎应返回复杂的对象。

问题:设计这样一个 Android 库的最佳方法是什么?

到目前为止,我只能找到 2 个有价值的示例:OpenCV managerConnectbot ssh-agent

我能想到几个解决方案:

  • 解决方案 1:制作一个包装库功能的(绑定或 AIDL)服务。(服务应该在自己的空间中运行?还是在链接到它的应用程序的空间中运行?如果它在不同的应用程序空间(System.load("/data/data/com.company.myLib/lib.so"))中如何加载本机库。如何在 AIDL 中返回复杂对象?)。这应该是 Connectbot 的方式。

  • 解决方案 2:将 lib 分为 2 个组件:

    1. 一个独立的包,它保留了本地库 + 一个管理器服务
    2. 一个 android lib-project,它只包含 Java 包装器,用户可以使用它来构建他们的应用程序。

    这应该是 OpenCV 管理器的方式。我不知道确切的细节,但这种方式不需要服务来接口并且可以只是import com.company.myLib.LibWrapper. 另一方面,LibWrapper 类应该执行System.load("/data/data/com.company.myLib/lib.so"). 正确的?

我个人会选择解决方案 2。不幸的是,Android 是一片新大陆,关于如何开发库的模型还不多。还有其他/更好的解决方案吗?还有其他需要考虑的吗?

4

1 回答 1

2

考虑以下方案:您构建了一个“空”应用程序,它不包含任何活动、没有设置 - 只有清单、“管理应用程序”列表的图标和系统安装在 /data/data/ package /中的本机库lib目录。

这个本机库可以但不必公开 JNI 函数。在典型情况下,该库将是开源 LGPL 库的直接移植 - 例如 libdmtx.so。

“客户端”应用程序将为“外部”库调用loadLibrary() ,然后为其 JNI 包装器调用通常的load() 。此库的唯一目的是将 Java 方法转换为外部库的公共 C API。

JNI 包装器和相应的 Java 类可以作为 .jar 或源分发,它们不受外部库的 LGPL 许可证的约束。

恕我直言,这种方案是确保 Android 上符合 LGPL 的唯一方法:任何人都可以从开源重新编译“外部”库,将其打包为“空”应用程序并将其安装在他们的设备上。

关于您对同时访问库的担忧,我实际上怀疑它是否如此重要:高端设备有四个核心,每个核心比便宜设备上的一个核心更强大。OTOH,使用 Linux 同步方法(例如命名管道)来跟踪活动实例很容易。

于 2012-10-05T20:18:41.093 回答