开发环境

创建一个 HelloJni 项目

  • 创建完成如下
  • 配置 Studio 下载安装 NDK,如果你之前已经单独下载过 NDK 也可以在 Project Structure -- SDK Location -- Android NDK location 下去引用,我更推荐如下方式通过 Android SDK Manager 自动安装,它会将 NDK 放入 /android-sdk/ndk-bundle/
  • 运行项目

将JNI构建功能添加到HelloJni项目中

Android Studio 通过 Google 开发的 experimental plugin 支持 native 开发,通过这个插件我们可以不用考虑配置麻烦的 Android.mk 等构建文件就可以进行开发,我们来将其添加到我们的项目中。
下面是 experimental 插件与 gradle 的版本对应表,详细查看官方文档,本教程我们将以 experimental plugin 0.7.3 为例

Plugin VersionGradle Version0.1.02.50.2.02.50.3.0-alpha32.60.4.02.80.6.0-alpha12.80.6.0-alpha52.100.7.0-alpha12.100.7.02.100.7.32.14.1

  • 对应的我们先配置项目的 gradle 版本为 gradle2.14.1,下载相应版本 gradle 并配置
  • 引用对应版本的 experimental 插件,此处以 0.7.3 版本为例,打开项目的 build.gradle

替换

classpath 'com.android.tools.build:gradle:2.2.0'

classpath 'com.android.tools.build:gradle-experimental:0.7.3'
  • 打开模块 的 build.gradle 文件,修改让它支持 experimental 插件的语法

替换

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.skyrin.hellojni"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
...

apply plugin: 'com.android.model.application'  //<<<

model {  //<<<
    android {
        compileSdkVersion 25
        buildToolsVersion "25.0.2"
        defaultConfig {
            applicationId "com.skyrin.hellojni"
            minSdkVersion.apiLevel 15  //<<<
            targetSdkVersion.apiLevel 25  //<<<
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles.add(file('proguard-android.txt'))  //<<<
            }
        }
    }
}  //<<<
...
  • 点击 Sync Now 同步项目

现在可以添加 Jni 代码了

  • 配置模块的 build.gradle 文件让它可以创建 hello-jni 动态链接库也就是 .os 等文件,然后 Sync 项目
        buildTypes {
            ...
        }
        //添加
        ndk{
            moduleName "hello-jni"
        }
  • 在 MainActivity 中(当然你也可以新建一个 JniUtils.class 进行封装)创建 native 方法
    ...
    static {
        System.loadLibrary("hello-jni");
    }

    public native String getStrFromJni();
    ...
  • 点击上面提示之后 Studio 会自动为我们创建 cpp 目录以及 .c 文件,c 文件生成代码如下
#include <jni.h>

JNIEXPORT jstring JNICALL
Java_com_skyrin_hellojni_MainActivity_getStrFromJni(JNIEnv *env, jobject instance) {

    // TODO


    return (*env)->NewStringUTF(env, returnValue);
}

替换其返回值如下

return (*env)->NewStringUTF(env, "Hello Jni!");
  • 调用 native 函数
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //调用jni代码
        ((TextView)findViewById(R.id.tv_jni)).setText(getStrFromJni());
    }

    static {
        System.loadLibrary("hello-jni");
    }

    public native String getStrFromJni();
}
  • 我们来 Run 一下
  • 用 c 写个加法函数试试

java

public native int add(int a,int b);

Jni

JNIEXPORT jint JNICALL
Java_com_skyrin_hellojni_MainActivity_add(JNIEnv *env, jobject instance, jint a, jint b) {

    // TODO
    return a+b;
}

调用

((TextView)findViewById(R.id.tv_jni)).setText(add(2,3)+"");
  • Run 一下

Congratulations! 你学会用 NDK 开发了✧*。٩(^㉨^)و✧