在上篇文章中,我介绍了C语言的一些常见操作,这篇文章步入正轨,开始对NDK进行深入浅出的探讨
本文是基于Android Studio 进行操作,由于最新的NDK已经整合了Cygwin,所以没有必要单独再去安装了。
配置:
1、打开Setting->Android SDK下载NDK
2、在Module下的build.gradle进行NDK的相关配置
同步一下
3、配置好SDK、NDK目录,虽然一般IDE会自动生成,但是还是确认下为好
在gradle.properties中
android.useDeprecatedNdk=true
配置好之后,正式开始开发NDK
1、创建一个Java 类
public class NdkUtil {
static {
System.loadLibrary("getStringFromNdk");//之前在gradle中配置的.so 名字
}
public native String getStringFromNdk();//native 代表调用原生方法
}
loadLibrary中传入的值就是之前在gradle中配置的so文件的名字,native代表调用原生方法,并且返回一个String数据类型。
2、生成.h的头文件
Build项目获得.class文件,打开Android Studio自带的控制台Terminal ,操作方法与DOS相近,首先,进入到项目的debug文件下,如:build\intermediates\classes\debug
接着对NdkUtil 进行编译,通过javah命令生成h文件
javah -jni com.adrian.ndkdemo.NdkUtil
如果提示找不到类文件,则说明你环境变量貌似配置有问题,可以这样写
javah -jni -classpath . com.adrian.ndkdemo.NdkUtil
我们可以看到在debug 下生成了一个h文件
我们可以打开看一下
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_adrian_ndkdemo_NdkUtil */
#ifndef _Included_com_adrian_ndkdemo_NdkUtil
#define _Included_com_adrian_ndkdemo_NdkUtil
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_adrian_ndkdemo_NdkUtil
* Method: getStringFromNdk
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_adrian_ndkdemo_NdkUtil_getStringFromNdk
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
里面包含一些头文件和一个方法
我们在main目录(java文件夹锁在目录)下新建一个名为jni的文件夹
把刚才生成的h文件剪切到该文件夹下
在文件夹下新建一个c文件,随意命名,我的为ndktest.c
Include 中传入h文件的路径
代码中的JNIEnv 是一个结构体,如果不懂的可以翻看我上一篇博客
传送门——C常用的操作
接着对JNI进行操作
代码如下:
#include "com_adrian_ndkdemo_NdkUtil.h"
JNIEXPORT jstring JNICALL Java_com_adrian_ndkdemo_NdkUtil_getStringFromNdk
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"调用NDK");
}
这时候你会发现出现大量的报错,这可能是Android Studio 本身存在的Bug,希望以后版本的IDE可以增强C代码的编译能力。。。
最后在Activity 调用NdkUtil的方法,我将从NDK获取的字符串用Toast显示出来了,代码如下:
public class MainActivity extends AppCompatActivity {
private Button mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button)findViewById(R.id.btn_get);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NdkUtil util = new NdkUtil();
Toast.makeText(MainActivity.this,util.getStringFromNdk(),Toast.LENGTH_LONG).show();
}
});
}
}
效果图:
Demo下载