JNI之hello world 分手后的思念是犯贱 2022-07-18 06:17 178阅读 0赞 ### 开发环境准备 ### * AndroidStudio 2.1.2 * SDK 23.0.3 * NDK android-ndk-r12b ### NDK安装与配置 ### * 下载NDK,[https://developer.android.com/ndk/downloads/index.html][https_developer.android.com_ndk_downloads_index.html] * 新建Android项目,打开Project Structure,默认情况下Android NDK Location一栏为空,配置一下就好,如图![这里写图片描述][20160907174743792] * 在项目的local.properties文件中,参照sdk配置路径,增加ndk配置路径,如ndk.dir=D:\\android-ndk-r12b ### Hello World JNI ### 1. 在MainActivity中创建native方法,如 public native String sayHello(); 2. 在项目src/main中创建jni目录,并创建hello.c,该目录主要存放c文件及头文件,如图![这里写图片描述][20160907174721146] 3. 在hello.c中编写如下代码:![这里写图片描述][20160907174828600] 1. 添加头文件,类似Java中的导包。这里必须加的是jni.h,这是Java与c/c++直接语言转换的核心文件,另外这里需要处理字符串,还需要引入string.h。 2. 添加java中native方法的实现。jstring代表返回值类型,Java\_com\_happy\_ndktest\_MainActivity\_sayHello:实现的方法名,固定格式,Java\_+所要实现方法的包名,其中包名.用\_替换。方法参数(JNIEnv \*env,jobject jobj):\*evn代表JNI环境变量env,jobj代表JNI环境对象。其中env和jobj方法中可能用不到,但也必须声明,源码中是这样说明的,env作为了一个JNINativeInterface指针,是java与c/c++之间的一个功能环境变量中间桥梁。 4. Gradle配置,在build.gradle中加入ndk moduleName,如下:这里的moduleName是在代码中loadLibrary所填写的名称,也是生成so包的lib后面的名称,与jni目录下的c文件名称没有关系![这里写图片描述][20160907175653352] 5. 在代码中调用,首先使用静态方法loadLibrary,然后就可以调用声明的native方法了,如下![这里写图片描述][20160907175429305] ### So包的产生 ### * 完成上述步骤,在android studio中产生so包是非常简单的。只需要rebuild一下项目,就产生各类abi版本下的so文件了,这些so文件都以libhello为名称的,这个名称是由lib+moduleName组成的。生成的so文件目录为:build\\intermediates\\ndk\\debug\\lib。![这里写图片描述][20160907175530462] ### So包的使用 ### * AndroidStudio中so包存放的目录默认是在main/jniLibs下面,如果没有这个目录可以创建并复制所有平台的so包到该目录下,一般情况我们比较倾向于把这些so包和jar包都放在app/libs下面,并且需要对gradle进行一下简单的配置,如下:添加这个配置,就是将main下面的确实jnilibs目录指定为libs,在系统加载so的时候会去libs目录下加载。 * 现在就可以注释掉gradle中的ndk关于moduleName的配置,像集成第三方SDK一样来运行我们自己的hello world了。![这里写图片描述][20160907175734056] ### PS ### 到上面那一步其实就已经完成so包的创建和使用了,在使用过程中我们基本都是使用的默认配置,当然我们可以进行在gradle中配置以致自己项目所需。在项目创建的基础上: * 添加需要支持的lib包: ldLibs(“log”) * 指定编译出所需的平台:abiFilters(“armeabi”, “armeabi-v7a”, “x86”) * STL支持:stl = “system”, STL目前可支持 system(系统默认的最小支持的C++运行时库);stlport\_static(以静态链接的方式使用stlport版本的STL);stlport\_shared(以动态链接的方式使用stlport版本的STL);gnustl\_static(以静态链接的方式使用gnu版本的STL) * cFlags标记: cFlags(“-std=c++11”) * 示例如下![这里写图片描述][20160907175935432] ### 小结 ### * 使用AndroidStudio进行JNI开发相对来说比以前在Eclipse中开发更加简便了,也不需要Android.mk,Application.mk等文件,这些完全可以在gradle中进行配置,具体需要配置那些信息可以参考gradle中的NdkOptions类,这个类就是上面配置ndk节点的对应java类。我们只需要关系写c文件以及和java直接的相互调用即可,省去了很多的麻烦,接下来,就可以玩转JNI开发了。 [https_developer.android.com_ndk_downloads_index.html]: https://developer.android.com/ndk/downloads/index.html [20160907174743792]: /images/20220717/0b493b80f9fa4fc0af897aa8e3cddf04.png [20160907174721146]: /images/20220717/8e5b5ddcda984e25a5018fad66226ad6.png [20160907174828600]: /images/20220717/3222c931108040c5af7cd492a89fde2c.png [20160907175653352]: /images/20220717/17b5732105764bdea9b9407399007c89.png [20160907175429305]: /images/20220717/bd61f95a287e4edda9721f5fa7e344a8.png [20160907175530462]: /images/20220717/1ebddb02091b41c5a6e002980a36ece6.png [20160907175734056]: /images/20220717/b931d0adae6a4b9fb1b79035c3efcb83.png [20160907175935432]: /images/20220717/7b8426c3633147ee981989a2757eb6e6.png
还没有评论,来说两句吧...