在上篇文章中,我介绍了C语言的一些常见操作,这篇文章步入正轨,开始对NDK进行深入浅出的探讨

本文是基于Android Studio 进行操作,由于最新的NDK已经整合了Cygwin,所以没有必要单独再去安装了。

配置:

1、打开Setting->Android SDK下载NDK

2、在Module下的build.gradle进行NDK的相关配置


Android中使用supervisorjob android中使用rangy库_java


同步一下

3、配置好SDK、NDK目录,虽然一般IDE会自动生成,但是还是确认下为好


Android中使用supervisorjob android中使用rangy库_Android_02


在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

Android中使用supervisorjob android中使用rangy库_Java_03

接着对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();
            }
        });
    }
}



效果图:

Android中使用supervisorjob android中使用rangy库_java_04

Demo下载