1. 安装和配置NDK
-
下载NDK,并解压NDK的zip包到非中文目录
-
配置path : 解压后NDK的根目录
eg: D:\software_download\android-ndk-r10;
2. 在AS中配置关联NDK
- local.properties中添加配置
ndk.dir=D\:\\software_download\\android-ndk-r10
- Project工程目录下gradle.properties文件中添加配置
android.useDeprecatedNdk=true
3. 编写native方法
在AS中新建一个Project,然后再新建一个class为JNIS,在内部声明native方法
public class JNIS {
public native String helloJNI();
}
4. 定义对应的JNI
-
在main下创建jni文件夹
-
生成native方法对应的JNI函数声明头文件
在cmd命令窗口中,切换目录到java目录下(D:\as_workspace\Project\testjni\src\main\java),运行命令 :
javah com.hx.testjni.JNIS
会生成com_hx_testjni_JNIS.h的头文件,内容为
#include <jni.h>
/* Header for class com_hx_testjni_JNIS */
#ifndef _Included_com_hx_testjni_JNIS
#define _Included_com_hx_testjni_JNIS
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_hx_testjni_JNIS
* Method: helloJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_hx_testjni_JNIS_helloJNI
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
-
将生成的头文件转移到jni文件夹下
-
在jni下定义对应的函数文件: test.c 内容如下:
#include "com_hx_testjni_JNIS.h" //引用生成头文件
JNIEXPORT jstring JNICALL Java_com_hx_testjni_JNIS_helloJNI
(JNIEnv * env, jobject jobj) {
return (*env)->NewStringUTF(env, "Hello from C");
}
- 在jni文件夹下创建一个空的C文件: empty.c
说明: 这是AS的bug, 必须至少2个C文件才能通过编译
5. 指定编译的不同CPU
在testjni Module目录下build.gradle文件中配置
android {
...
defaultConfig {
...
ndk{
moduleName "HelloJni" //so文件: lib+moduleName+.so
abiFilters "armeabi", "armeabi-v7a", "x86" //cpu的类型
}
}
}
6. 编译生成不同平台下的动态链接文件
点击AS工具栏中的Build-->Rebuild Project,生成 .so文件 (so文件目录: build\intermediates\ndk\debug\lib\ndk\debug\lib...)
7. 调用native方法
- 在native方法所在的类(JNIS类中)中加载so文件
public class JNIS {
static {
System.loadLibrary("HelloJni"); //加载.so文件
}
public native String helloJNI();
}
- 在Activity中调用native方法:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String result = new JNIS().helloJNI();
Log.e("TAG", "result=" + result);
Toast.makeText(this, result, Toast.LENGTH_SHORT).show();
}
}
下面为项目的目录结构图: