安卓中的NDK是如何工作的 - NDK、JNI等的使用顺序是什么?

11

Java、NDK、JNI、JVM和C/C++代码等在Android项目中是如何相关联的?

我想知道例如Java代码运行NDK方法时会发生什么,NDK使用JNI库或其他任何情况。另外NDK和JNI之间有什么区别。

如果这个问题表述不清楚的话,请见谅,我只是对如何在Android项目中实现NDK感到困惑。


可能是Jni 教程 for Android的重复问题。 - mach
1个回答

21
NDK用于将C/C++/汇编代码编译成二进制文件。使用NDK可以完成许多任务,例如编译可执行文件、静态预构建等,但最终,在Android应用程序的上下文中,您会获得一个或多个.so文件(共享对象库)。
从Java中,您可以加载这些.so文件并映射在其中实现的函数。特定情况是,Android应用程序项目仅包含C/C++代码(请参见NDK中的"native-activity"示例),但这仍然是相同的原理:.so文件在ART或Dalvik上下文中加载。
Android应用程序中的任何内容都在Dalvik虚拟机或ART的上下文中执行。为了将C/C++代码集成到此环境中,您需要使用JNI(Java Native Interface)。
首先,您使用JNI机制:当您加载.so文件时,如果存在,则会调用其JNI_OnLoad()函数,并将以Java_开头的函数映射到相应的Java方法。这些方法应在Java类中声明,并具有关键字native,以指定其实现来自.so文件。.so文件使用System.loadLibrary()加载,通常位于将方法声明为native的Java类的静态块中。
在运行时,当Java执行到其实现在.so文件中的方法并已加载该.so文件时,直接执行此本地实现。当它返回时,Java代码执行继续。
JNI还提供jni.h头文件,该文件提供了访问Java环境(JavaVM*,JNIEnv*)的方法,因此您可以操纵、创建和访问Java基元(jint、jlong...)、对象(jobject、jclass..)、异常(jthrowable)等。
为了正确打包、安装并使用System.loadLibrary加载,必须将.so文件放置在特定位置:
  • 在eclipse项目中的libs/CPU_ABI
  • 在Android Studio项目中jniLibs/CPU_ABI

  • 在AAR内的jni/CPU_ABI

当应用程序打包成APK时,libs位于其lib/CPU_ABI文件夹内。

在安装过程中,针对目标平台的libs被安装到<5.0设备上的nativeLibraryPath中,在>=5.0设备上则位于应用程序的legacyNativeLibraryDir/CPU_ARCH内。

这里的CPU_ABI可以是以下任意一种:armeabi、armeabi-v7a、arm64-v8a、x86、x86_64、mips、mips64,具体取决于你要面向哪些架构以及你的libs是否已经编译完成。


非常感谢,这正是我正在寻找的。 - user3185731
选择所有架构后,编译是在什么时候进行的?这是在用户安装应用程序时发生的事情吗?还是APK包含了您选择的所有架构/ABI的.so文件? - Jerinaw
在应用程序发布之前,需要编译.so文件。您可以为要支持的架构/ABI拥有一个APK,其中包含零个(纯Java)、一个或多个.so文件集合。 - ph0b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接