我想生成一个SO文件及其相应的Java接口,以便将其用于另一个项目。
到目前为止我做了什么:
我在Android Studio 2.3.3(2017-08-09的最新版本)中创建了一个项目,其中包含“Include C ++ support”并编写了一些C / C ++代码并对其进行编译,当我运行该程序时,它成功了调用并返回“来自JNI的Hello”字符串。
之后,我查看了生成的.so
文件的输出,但是我找不到这个文件。之后,我在输出文件夹中找到生成的APK文件,当我解压缩时,我发现这些文件夹都包含.so
文件:
现在问题是,如何将这些.so
文件用于另一个项目,因为我在互联网上搜索了很多,但不幸的是,我没有找到任何解决方案,他们提到的解决方案全部是在项目名称main
的{{1}}文件夹中创建一个文件夹,并在修改了Gradle文件后...,但没有人工作。
在这里,我想知道如何添加.so文件和相应的Java接口以在项目中使用它们?
现在我在尝试调用.so文件中的JNI函数时进入新项目是错误。
答案 0 :(得分:2)
这些.so文件位于不同的文件夹中,因为不同的设备具有不同的体系结构,并且链接a以使其不兼容将导致失败。 How to find ARM processor version on android device?展示了如何使用终端获取android架构(还有一个Java的内部api)。
您可以将JNI项目作为android库/模块,以便您可以轻松地将其集成到其他项目中。您需要编写一个包装器。大多数第三方图书馆都使用这种方法。
您可以创建另一个C ++项目,然后将构建文件夹复制到新项目lib文件夹中。然后,您需要在CMakeLists.txt中添加这些库依赖项。但是,您仍然需要创建一个可以调用库的jni接口。在CMakeLists中,您需要使用
include_directories(path_to_your_include)
add_library( lib_yourlib SHARED IMPORTED )
set_target_properties(lib_yourlib PROPERTIES IMPORTED_LOCATION path_to_your_abi_folders/${ANDROID_ABI}/yourlib.so)
展示第一种方法的GitHub项目 https://github.com/khedd/SimpleAndroidModule
答案 1 :(得分:1)
我找到了解决这个问题的方法。 我不知道这是否是解决问题的好方法。
当您使用“包含C ++支持”创建项目并编写本机(C / C ++)代码,然后运行应用程序,如果一切正常,那么您可以查看生成文件夹中生成的.so文件在以下路径中:打开它,您将看到单独文件夹中所有平台的.so文件。
现在创建一个新项目并将项目视图更改为“项目”视角:
复制并粘贴'app'的libs文件夹中的所有文件夹:
然后在Gradle文件中添加以下代码:
task nativeLibsToJar(type: Zip, description: "create a jar archive of the native libs") {
destinationDir file("$projectDir/libs")
baseName "Native_Libs"
extension "jar"
from fileTree(dir: "libs", include: "**/*.so")
into "lib"
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(nativeLibsToJar)
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
添加代码后,Gradle文件如下所示:
完成后,同步Gradle文件:
从Build菜单中创建项目:
完成此过程后,将项目视图更改为Android,您将在其中看到“jniLibs”文件夹和生成的.jar文件:
现在去创建一个新项目,不做任何事情只是将.jar文件复制并粘贴到libs文件夹中:
现在右键单击并选择“添加为库”:
选择“本地库位置”并单击“确定”,然后在下一个对话框中再次单击“确定”。
现在,在第一个项目中编写C / C ++代码的同一个包中创建相同的类。并通过以下方式调用来加载lib:
System.loadLibrary("native-lib");
之后,IDE将在本机方法上出错,不关心并完成您的工作。
注意: 本机方法类必须与创建的名称和名称相同,否则无法找到该方法。
希望这可以帮助那些与JNI有同样问题的人。