gpt4 book ai didi

java - 在 Android JUnit 测试中加载 native 库

转载 作者:太空狗 更新时间:2023-10-29 22:57:26 27 4
gpt4 key购买 nike

我使用 ndk-build 生成了一个本地库我可以在我的 Android 应用程序中加载和使用它。但是,我想针对我的应用程序的这一部分编写一些测试。

在我的测试中调用 native 函数时,我收到此异常消息:

java.lang.UnsatisfiedLinkError: no process in java.library.path

...哪里process是我要导入的原生库,名为 libprocess.so .

我正在使用 Roboelectric 进行测试,并使用 RobolectricTestRunner 运行这个特定的测试,如果它有所作为。

如何让我的测试项目“看到” native 库?


编辑:我正在像这样在我的应用程序中加载库:

static {
System.loadLibrary("process");
}
public static native int[] process(double[][] data);

调用 Process.process(array)在应用程序中运行良好(库已加载),但从测试运行时失败,但出现上述异常。


编辑 2:如果我设置 -Djava.library.path="<the directory of libprocess.so>"作为 VM 参数,则:

System.out.println(System.getProperty("java.library.path"));

确实显示了我设置的路径,但我仍然遇到相同的异常。我将目录设置为:

<project-name>/libs/x86

...但作为绝对路径。

最佳答案

对于仍在寻找的人来说,blork 的想法是正确的 - 您需要为“本地”平台(Windows、Linux、Mac)编译本地库。 Android NDK 为 Android 平台构建库(.so 文件 - 也可能在 Linux 上工作),这就是为什么在 Activity 测试用例中运行没有问题(因为它加载了一个 Android 实例)。

要运行低级、快速的 JUnit 测试,您需要支持您的 JVM。在 Windows 上,这可能是构建 DLL,在 Apple 上,它是在构建动态库(假设共享库)。

我刚刚在我的 android-ndk-swig-example 存储库 ( https://github.com/sureshjoshi/android-ndk-swig-example/issues/9 ) 中完成了一个示例。

基本上,在我的 CMakeLists 中,我添加了 Apple 警告:

# Need to create the .dylib and .jnilib files in order to run JUnit tests
if (APPLE)
# Ensure jni.h is found
find_package(JNI REQUIRED)
include_directories(${JAVA_INCLUDE_PATH})

然后我确保 Gradle 运行单元测试,但使用 Mac 构建系统(不是 NDK)。

def osxDir = projectDir.absolutePath + '/.externalNativeBuild/cmake/debug/osx/'

task createBuildDir() {
def folder = new File(osxDir)
if (!folder.exists()) {
folder.mkdirs()
}
}

task runCMake(type: Exec) {
dependsOn createBuildDir
workingDir osxDir // Jump to future build directory
commandLine '/usr/local/bin/cmake' // Path from HomeBrew installation
args '../../../../' // Relative path for out-of-source builds
}

task runMake(type: Exec) {
dependsOn runCMake
workingDir osxDir
commandLine 'make'
}

project.afterEvaluate {
// Not sure how much of a hack this is - but it allows CMake/SWIG to run before Android Studio
// complains about missing generated files
// TODO: Probably need a release hook too?
javaPreCompileDebug.dependsOn externalNativeBuildDebug
if (org.gradle.internal.os.OperatingSystem.current().isMacOsX()) {
javaPreCompileDebugAndroidTest.dependsOn runMake
}
}

警告时间!!!

当您使用此方法时,从技术上讲,您并不是在测试 NDK 生成的库。您正在测试相同的代码,但使用不同的编译器(msvc、xcode、gcc、clang,无论您在主机上使用什么)编译。

这实际上意味着大多数测试结果都是有效的——除非你遇到由每个编译器的怪癖或 STL 实现等引起的问题……这不像 10+ 时那么糟糕几年前,但您不能 100% 肯定地说使用主机库的 JUnit 测试结果与 Android 库相同。不过,您可以说它相当接近。

话又说回来,除非您使用 Android NDK 为每个受支持的架构运行 native 单元测试,否则您也不能说任何关于确定性的事情……所以从中获取您想要的。

一种矫枉过正的方法(但如果自动化的话真的很酷)是编写你的原生单元测试,但是你这样做(谷歌测试,Catch 等),然后编译并运行你的原生库和单元测试每个都有 Android NDK建筑学。这提供了您对潜在目标体系结构的 C/C++ 覆盖。

从这里开始,您可以将上述主机库与 JUnit 结合使用,以快速对与 native 库交互的 JNI 层进行单元测试。在您的 CI 系统中,您可能仍然应该运行这些相同的单元测试——但作为 Android Instrumentation 测试(或运行模拟 Android 环境的其他东西)。

与所有事物一样,只要有界面,您就可以创建模拟 - 但在某些时候,您也需要系统/功能/集成测试。

更新:

在博客文章 ( http://www.sureshjoshi.com/mobile/android-junit-native-libraries/ ) 中对上述内容进行了更全面的解释

关于java - 在 Android JUnit 测试中加载 native 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16539684/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com