【问题标题】:Creating a product SDK: How do I add a native lib (.so) and a jar with the SDK I am creating?创建产品 SDK:如何使用我正在创建的 SDK 添加本机库 (.so) 和 jar?
【发布时间】:2011-06-20 09:51:00
【问题描述】:

我正在创建一个小部件,我们将提供给开发人员最终用户,它由一个 .jar 和一个使用 NDK 构建的本机库 (.so) 组成。 JAR 有一个到动态库的 JNI 接口。

关于如何在项目中包含外部.jar 非常清楚,但不知道如何包含依赖的动态库。

  1. 如何打包和构建.jar.so?这里有哪些最佳实践?

  2. 我可以使用 JDK 的 jar 命令创建 JAR 文件。我是否需要在 jar 上运行 dx.bat 才能转换为 Dalvik 字节码?

  3. 我需要创建一个示例项目来显示小部件的运行情况。如何在演示如何使用小部件的示例项目中包含此 .jar.so

【问题讨论】:

    标签: android jar android-ndk


    【解决方案1】:

    您应该为此使用 SDK 中包含的标准构建工具。如果您在项目的/lib 目录中包含所需的 .jar 文件,则 ant 构建过程会将包含的类文件转换为 Dalvik 字节码格式,并将它们包含在应用程序的 classes.dex 文件中。将build.properties 文件也添加到您的项目根目录,只需一行:

    external.libs.dir=lib

    根据您的 SDK 版本及其配置,您可能需要将 jar 放在 libs 而不是 lib

    至于 .so,我认为它是使用 Android NDK 正确编译的,或者使用的构建脚本使用了正确的编译器和编译器标志,这些是在 Android 上成功链接共享对象所需的。如果是这种情况,您可以将 .so 文件包含在 libs/armeabi 中,它们也会添加到 jar 中。此外,当您实际尝试从 Java 代码加载库时,动态库加载器会知道在 .jar 中查找此位置。

    【讨论】:

    • 这种工作。我确实需要为我的 JAR 使用 LIBS 文件夹,但在缺少类型时出现编译错误。 Eclipse 希望我通过将库项目添加到我的示例项目来“修复项目”。我还能尝试什么?
    • 如果您从示例项目中引用 jar,那么您确实需要将 jar 添加到示例项目中,因此它知道在哪里可以找到类型的定义。您可以直接在 .classpath 文件中添加一行,看起来像 <classpathentry kind="lib" path="lib/jmdns.jar"/>,或者转到项目属性的 Libraries 选项卡下的 Java Build Path 部分,并使用 Add JARs... 按钮添加它。
    • 我试图在我的 JAR 中包含一个 .so 并且发现客户端项目将不再构建。 The library 'foo.jar' contains native libraries that will not run on the device. The following libraries were found: libs/armeabi/libfoo.so Android SDK 技术主管 Xavier Ducrohet 表示,他对 this thread on the NDK Google Group 表示重视,他们在包含的 JAR 中添加了对本机代码的检查
    • @Kevin,您可以在 Eclipse 中使用 Window -> Preferences -> Android -> Build -> Force error when external jars contain native libraries 禁用此检查
    【解决方案2】:

    使用 ADT 12,我完成了以下操作:

    1) 使用 Eclipse 从库中导出带有 SO 文件的 JAR。确保排除 AndroidManifest.xml。这将包括源代码和其他数据,因此如果您正在分发,您需要使用任何 ZIP 实用程序去除这些不必要的部分。

    2) 在您的应用程序的源代码树中创建一个目录(我使用“lib”目录)并将您的库 JAR 复制到其中。

    3) 在 Eclipse 中右键单击项目并选择“配置构建路径”。添加 JAR 并将其指向应用程序源树中的 JAR。

    4) 在您的 Eclipse 首选项中,选择 Android/Build 部分并取消选中“Automatically refresh Resources and Assets folder on build”。您会注意到下面的一个选项,上面写着“当外部 jar 包含本机库时强制出错”。有一个 ADT 错误,据说会在 R17 中修复,它使用了错误的设置。修复后,您将使用“强制错误”(确保未选中)。

    5) 构建应用 APK 后,您将拥有一个 libs/armeabi/libXXXX.so 文件。这不会在安装时自动解压缩。您需要编写代码将其从 APK 文件中提取到数据目录中,然后在数据目录中的 .so 文件上使用 System.load。

    我有来自动态加载文件的双向 JNI 调用,甚至使用 dlopen() 来完成我的自定义插件注册工作。

    【讨论】:

    • 如何编写代码从apk文件中提取so文件。我已经将so文件添加到jar中。非常感谢您的帮助。
    • 很遗憾,我再也无法访问这段代码,而且时间太长了,以至于我忘记了大部分细节。但是由于 APK 是一个 ZIP 文件,因此任何 ZIP 库都应该能够为您处理这个问题。祝你好运。
    【解决方案3】:

    我花了一些时间在这上面,我只是不明白为什么这不是写在 wikiitude 文档上的......无论如何都要遵循这些变化!

    • 转到 windows/preferences/android/build
    • 取消选中第一个和第二个选项
    • 使用 winrar 从 wikitudesdk.jar 中提取文件,就像它是一个存档一样,搜索 libarchitect.so 并将其复制到 /libs/libs/armeabi/ 中
    • 将 wikitudesdk.jar 添加到您的构建路径

    【讨论】:

      【解决方案4】:

      将以下行添加到android.mk

      include $(BUILD_PACKAGE)
      
      LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := alias:libs/your.jar
      
      include $(BUILD_MULTI_PREBUILT)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-17
        • 1970-01-01
        • 1970-01-01
        • 2015-12-12
        相关资源
        最近更新 更多