本帖最后由 武汉分校-小舞 于 2017-8-17 15:10 编辑
今天看了一些博客写的关于ndk开发的,要么太老,要么太复杂。我就把我知道的简单一点方式的分享给大家。 ##一:环境配置: 首先下载好NDK,网上一堆,自己找。 然后在AndroidStudio中配置好NDK,如下图:
![ndk环境配置.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 再配置好NDK环境变量,配置好之后在黑窗口测试一把,出现如下界面就已经可用了 ![环境变量演示.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ##二:开发流程 ####1、新建一个module或者使用工程中的app。 ####2、在app中的MainActivity里面写如下代码(这行代码你愿意写在哪都行,也可以自己新建一个类里面写这行代码): ``` public native String getStringFromJNI(); //方法名随意,你开心就好。 ``` ####3、打开AS中的Terminal,然后输入如下命令: ``` cd app/src/main/java //切换到该目录下
javah -jni com.example.demo.MainActivity //后面就是你所写的native方法所在类的全路径 ``` 这样你就能在你所写native方法所在类的同级目录下拿到一个.h文件。
![h文件所在目录.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 打开这个.h文件看到如下信息:
![h文件内容.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 其中有用的就是这行代码: ``` JNIEXPORT jstring JNICALL Java_com_example_demo_MainActivity_getJNIString (JNIEnv *, jobject); ``` 接下来我们需要根据这行代码写c文件。 ####4、写C文件 首先在app目录下也就是libs文件夹同级目录下建一个文件夹jni(这个文件夹你可以建在任意位置,但是他会在再成一个libs文件夹来存放编译出来的so文件,放在同级目录下就会直接生成到app中的libs文件夹里面,大家可以试试)。 然后在jni文件夹下面建一个.c文件,文件名随意。
![新建c文件.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
![新建c文件_1.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 创建好c文件例如jnidemo.c 在这个文件中加入如下代码: ``` #include <jni.h> JNIEXPORT jstring JNICALLJava_com_example_administrator_ndkapp_MainActivity_getCString (JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env, "这是jni传给我的"); } ``` 细心的朋友就发现了,这里面写的是不是就是之前的.h文件生成的那些东西,只不过是帮他实现了,.h知识相当于调用,这里是具体实现类。 ps:不要问我代码什么意思,这样写就完了。这只是一个小入门demo,正真开发中会让你写C? ####5、创建Android.mk文件 还是在jni目录下,创建Android.mk文件,改文件中写进如下代码: ``` LOCAL_PATH := $(call my-dir) //固定写法,不要纠结 include $(CLEAR_VARS) //固定写法,不要纠结 LOCAL_MODULE:=jnidemo //这里是你马上要生成的so文件的名字,系统会默认在这个名字之前加一个lib LOCAL_SRC_FILES :=jnidemo.c //这个就是你刚才写的那个c文件的名字 include $(BUILD_SHARED_LIBRARY) //固定写法,不要纠结 ``` ####6、开始生成so文件 打开Terminal,输入: ``` cd app //切换到jni所在目录上一级 ndk-build ``` 如果不出意外你就会开到lib中的so文件了。 ####7、如果仅仅这样写就只是生成了一种armeabi的so文件这不能满足我们的需求我们需要兼容各种类型
![libs.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 其实只需要一步就完成了,相教与之前在build.gradle中配置,这样写也很简单。 我们只需要在建一个Application.mk文件就好了,在其中配置如下代码。 ``` APP_ABI := all //这样就能生成所有类型的so了,如果需要指定也可以如: //APP_ABI := armeabi x86 ``` 然后在进行一次第6步的操作就ok了。
###三:调用so中的方法 有了so文件之后,就可以调用自己写的native方法了,虽然这个方法还是红的,但是不影响运行。调用步骤如下 ####1、在app目录下的gradle中android节点下配置如下信息: ``` sourceSets{ main{ jniLibs.srcDirs=['libs'] }
} ``` ####2、在初始化中加载so文件,我是在Activity中加入静态代码块如下: ``` static{ System.loadLibrary("jnidemo"); //引号中的内容,是你在Android.mk指定的so文件的名字,不是libjnidemo哦。 } ``` 然后就可以开始调用这个方法咯! |