Android Stuido Ndk-Jni 开发(一):创建简单的JniDemo
Java Native Interface(JNI)即java本地接口,它允许Java代码和其他编程语言(主要是C/C++)的代码进行交互。native实现的代码的效率可以比java高,有一些对运行效率要求比较高的场合需要用到Jni。有时候需要调用C/C++编写的代码,也需要用到Jni。所以Jni开发在android开发里面有特殊的作用。本文就从创建一个简单的JniDemo讲起。
环境配置
下载ndk,墙内官网访问不了,可以度娘,现在最新的是
android-ndk-r10e-windows-x86_64.exe解压,一般是解压到与SDK同级的目录下:
- 设置Windows环境变量
然后在Path里面添加%Android_NDK_HOME%
新建工程
1. 打开android studio,新建工程
选择新建一个Empty Actity
2. 新建NativeHelper类,声明一个native方法:
声明代码如下:
public class NativeHelper {
public native String getStringFromJni();
}
3. 执行Build->Make Project,目的是生成class文件
打开工程目录HelloJni\app\build\intermediates\classes\debug\com\dj\jni\hellojni\NativeHelper.class 可以看到生成了NativeHelper.class文件:
4. 根据class文件生成对应的c语言头文件
打开android stuido 的 terminal,执行命令cd app/src/main
进入mian目录,目的是在mian目录下生成jni文件夹。
然后用javah生成c头文件:
javah -d jni -classpath D:\ANDROID_DEVELOP_ENVIRNMONT\SDK\platforms\android-21\android.jar;..\..\build\intermediates\classes\debug com.dj.jni.hellojn
i.NativeHelper
命令格式是:
javah -d (jni文件夹名) -classpath (sdk路径);(class路径) (class完整的文件名,包括包名)
然后再看main目录下会多出jni文件夹,里面已经自动生成了一个头文件com_dj_jni_hellojni_NativeHelper.h
文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_dj_jni_hellojni_NativeHelper */
#ifndef _Included_com_dj_jni_hellojni_NativeHelper
#define _Included_com_dj_jni_hellojni_NativeHelper
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_dj_jni_hellojni_NativeHelper
* Method: getStringFromJni
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_dj_jni_hellojni_NativeHelper_getStringFromJni
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
5. 新建.c文件
在jni文件下新建.c文件,当然新建.cpp文件也是可以的啦,就看大家习惯使用c还是c++
添加内容如下:
#include <jni.h>
/*
* Class: com_dj_jni_hellojni_NativeHelper
* Method: getStringFromJni
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_dj_jni_hellojni_NativeHelper_getStringFromJni
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"Hello from JNI !");
}
6. 配置ndk ###
执行Build->Clean Project, 再执行Build->Make Project,期间可能会提示错误:
我们根据提示在gradle.properties文件中添加以下内容:
android.useDeprecatedNdk=true
打开File->Project Structure,选择ndk的路径
在app目录下的build.gradle中设置要生成的so库文件名,在defaultConfig这项里面添加:
ndk {
moduleName "HelloJni" //编译后会生成HelloJni.so
}
在NativeHelper类中添加对so库的加载:
static {
System.loadLibrary("HelloJni");
}
android动态加载库文件有两个方法,System.load 和 System.loadLibrary
System.load 参数必须为库文件的绝对路径
System.loadLibrary 参数为库文件名,不包含库文件的扩展名。
注意加载的库名字要与build.gradle中配置的库名字一致。
NativeHelper类的完整代码如下:
7. 编译jni, 调用native方法
再执行Build->Clean Project,
执行Build->Make Project。
打开工程目录HelloJni\app\build\intermediates\ndk\debug\lib 可以看到生成了各个平台的so文件:
注意: 每次修改jni文件夹下的.c文件或者.h文件都要重新执行Build->Make Project,重新生成so文件。
打开MainActivity,调用native方法:
运行结果: