在 Android Studio 中让本机代码在模块中工作时出现问题
Problem getting native code to work in a module in Android Studio
我正在尝试构建一个 Android 库,其中包含本机代码和调用 C++ 代码的 Java 代码的组合。 C++ 严格限于库。我设法编译了一个项目,但是当我启动单元测试时,出现找不到库的异常。
我检查过,代码确实生成了 .so 文件,但就是找不到它们。
因此,我创建了一个空的 activity 项目并在其中为 Android 库创建了一个模块。
在其中,我将我的代码和一个 CMakeLists.txt
文件放在 src/main/cpp
目录中:
libnative.cpp
:
#include "libnativeJNI.h"
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL GEN_FUNCNAME(TestFunction)(JNIEnv *jenv, jobject jobj)
{
return 0;
}
#ifdef __cplusplus
}
#endif
libnative.h
:
#ifndef NDKTROUBLESHOOT_LIBNATIVEJNI_H
#define NDKTROUBLESHOOT_LIBNATIVEJNI_H
#include "jni.h"
#define GEN_FUNCNAME(FUNCNAME) Java_com_java_libnative_libnative_##FUNCNAME
#endif //NDKTROUBLESHOOT_LIBNATIVEJNI_H
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.10.2)
project("LibNative")
add_library(LibNative SHARED libnativeJNI.cpp)
find_library(log-lib log)
target_link_libraries(LibNative ${log-lib})
我还通过在 android
部分添加以下行来更新模块内部的 gradle 以编译本机代码:
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
}
}
本机代码链接到 src/main/java/com/java/libnative/
中的 Java class:
libnative.java
:
package com.java.libnative;
public class libnative {
static
{
System.loadLibrary("LibNative");
}
private native int TestFunction();
public libnative()
{
TestFunction();
}
}
我还可以看到在库中编译的本机代码 libnative/build/intermediates/cmake/debug/obj/{Architecture}/libLibNative.so
。
现在,IDE 可以识别原生函数,但我在模块中创建了一个单元测试来测试它是否真的有效:
package com.java.libnative;
import org.junit.Test;
public class UnitTest {
@Test
public void library_canLoad()
{
new libnative();
}
}
但是,这样做会在 运行:
上触发异常
java.lang.UnsatisfiedLinkError: no libnative in java.library.path
我缺少什么来完成这项工作?
结果如Michael所述,测试环境不支持加载本地库。我通过将相同的代码发送到捆绑在应用程序中的 phone 来测试它,它工作正常。
因此在这种情况下,不幸的是单元测试不能用来测试库。
我正在尝试构建一个 Android 库,其中包含本机代码和调用 C++ 代码的 Java 代码的组合。 C++ 严格限于库。我设法编译了一个项目,但是当我启动单元测试时,出现找不到库的异常。
我检查过,代码确实生成了 .so 文件,但就是找不到它们。
因此,我创建了一个空的 activity 项目并在其中为 Android 库创建了一个模块。
在其中,我将我的代码和一个 CMakeLists.txt
文件放在 src/main/cpp
目录中:
libnative.cpp
:
#include "libnativeJNI.h"
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL GEN_FUNCNAME(TestFunction)(JNIEnv *jenv, jobject jobj)
{
return 0;
}
#ifdef __cplusplus
}
#endif
libnative.h
:
#ifndef NDKTROUBLESHOOT_LIBNATIVEJNI_H
#define NDKTROUBLESHOOT_LIBNATIVEJNI_H
#include "jni.h"
#define GEN_FUNCNAME(FUNCNAME) Java_com_java_libnative_libnative_##FUNCNAME
#endif //NDKTROUBLESHOOT_LIBNATIVEJNI_H
CMakeLists.txt
:
cmake_minimum_required(VERSION 3.10.2)
project("LibNative")
add_library(LibNative SHARED libnativeJNI.cpp)
find_library(log-lib log)
target_link_libraries(LibNative ${log-lib})
我还通过在 android
部分添加以下行来更新模块内部的 gradle 以编译本机代码:
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
}
}
本机代码链接到 src/main/java/com/java/libnative/
中的 Java class:
libnative.java
:
package com.java.libnative;
public class libnative {
static
{
System.loadLibrary("LibNative");
}
private native int TestFunction();
public libnative()
{
TestFunction();
}
}
我还可以看到在库中编译的本机代码 libnative/build/intermediates/cmake/debug/obj/{Architecture}/libLibNative.so
。
现在,IDE 可以识别原生函数,但我在模块中创建了一个单元测试来测试它是否真的有效:
package com.java.libnative;
import org.junit.Test;
public class UnitTest {
@Test
public void library_canLoad()
{
new libnative();
}
}
但是,这样做会在 运行:
上触发异常java.lang.UnsatisfiedLinkError: no libnative in java.library.path
我缺少什么来完成这项工作?
结果如Michael所述,测试环境不支持加载本地库。我通过将相同的代码发送到捆绑在应用程序中的 phone 来测试它,它工作正常。
因此在这种情况下,不幸的是单元测试不能用来测试库。