我使用ndk-build生成了一个本机库,我可以在我的Android应用程序中加载和使用它.但是,我想针对我的应用程序的这一部分编写一些测试.
在我的测试中调用本机函数时,我收到此异常消息:
java.lang.UnsatisfIEdlinkError: no process in java.library.path
…进程是我要导入的本机库,名为libprocess.so.
我正在使用Roboelectric进行测试,并使用RobolectricTestRunner运行这个特殊的测试,如果它有所作为的话.
如何让我的测试项目“看到”本机库?
编辑:
我正在我的应用程序中加载库,如下所示:
static { System.loadlibrary("process");}public static native int[] process(double[][] data);
调用Process.process(array)在应用程序中运行正常(库已加载),但在从上面给出的异常测试运行时失败.
编辑2:
如果我设置-Djava.library.path =“< 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 Test Cases中运行没有问题(因为它加载了一个AndroID实例).
要使低级别的hella fast JUnit测试运行,您需要支持您的JVM.在windows上,这可能是在Apple上构建DLL,它正在构建dylib(假设是共享库).
我刚刚在androID-ndk-swig-example repo(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 testsif (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? java@R_981_3013@eBUG.dependsOn externalNativeBuildDeBUG if (org.gradle.internal.os.OperatingSystem.current().isMacOsX()) { java@R_981_3013@eBUGAndroIDTest.dependsOn runMake } }
CAVEAT TIME !!!
当您使用此方法时,您在技术上不会测试NDK生成的库.您正在测试相同的代码,但使用不同的编译器(msvc,xcode,gcc,clang,无论您在主机上使用什么)编译.
实际上,这意味着大多数测试结果都是有效的 – 除非你遇到由每个编译器的怪癖或STL实现等引起的问题……这不像10年前那么糟糕,但是您无法100%确定地说,使用主机库进行JUnit测试的结果与AndroID库相同.不过,你可以说它相当接近.
再说一次,除非你为每个支持的架构使用AndroID NDK运行本机单元测试,否则你也无法确定任何关于确定性的事情……所以你要从中得到它的意思.
一种过度杀伤的方法(但是如果自动化的话真的很酷)就是编写你的原生单元测试但是你会这样做(Google Test,Catch等),然后使用每个架构的AndroID NDK编译和运行你的本机库和单元测试.这为您的潜在目标架构提供了C/C++覆盖.
从这里开始,您可以使用前面提到的主机库和JUnit来快速单元测试与您的本机库交互的JNI层.在您的CI系统中,您仍然应该运行这些相同的单元测试 – 但是作为AndroID Instrumentation测试(或运行模拟AndroID环境的其他东西).
与所有内容一样,只要有接口,就可以创建模拟 – 但在某些时候,您还需要系统/功能/集成测试.
更新:
博客文章(http://www.sureshjoshi.com/mobile/android-junit-native-libraries/)中对上述内容的更全面解释
总结以上是内存溢出为你收集整理的java – 在Android JUnit测试中加载本机库全部内容,希望文章能够帮你解决java – 在Android JUnit测试中加载本机库所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)