综述

想尝试Android jni编程。没想到在编写hellojni的时候就遇到了很大的问题。幸好所有的问题都被克服,下面就说一下个人认为需要注意的事项安利给大家。

环境配置

配置ndk

在用Android studio之前,我本身已经有了ndk,然而,并没有什么卵用。Android studio不支持我导入本地的ndk,害的我费了好多vpn流量去下载。配置ndk的方法是先“close project”进入欢迎界面,在”quick start”中进入“configure”页面,然后进入“project default”进入“project structure”,其中最后一项就是要你配置ndk的路径,然而并不会让你直接导入你自己的本地ndk,需要你克服GFW在线下载。

配置gradle

进入编辑界面,切换到project目录,编辑gradle目录下的local.properties,在末尾加上自己的sdk路径和ndk路径。格式如下

ndk.dir=D\:\\Android_sdk\\Android_sdk\\ndk-bundle
sdk.dir=D\:\\Android_sdk\\Android_sdk

在app的build.gradle文件中default config中加入。

ndk {
     moduleName "hellojni"
     ldLibs "log", "z", "m"
     abiFilters "armeabi", "armeabi-v7a", "x86"
}

其中hellojni是你在System.loadLibrary中加载的库名。
这样做在有些平台上不能编译通过,需要再gradle的gradle.properties中加入以下声明

android.useDeprecatedNdk=true

编写源码

编写Java源码

1,编写一个声明了native函数的类,类似

public class JNIUtils {
    static{
        System.loadLibrary("hellojni");
    }
    //public static native String getStringFromNative();
}

注意:为了保证这个类能编译通过把native函数的声明先注释掉。
2,build这个类
点击工具栏build->Rebuild Project,在工程的project视窗下进入

app->build->intermediates->classes->debug->xxx

查看之前那个类是否编译为classes,如果没有,重新rebuild,如果存在了classes类,进入terminal,cd到debug目录,执行类似下面的命令

javah renwj.com.hellojni.JNIUtils

执行成功之后把生成的.h文件复制到src->main->jni目录中。
3,编写调用到native函数的java文件

编写C源码

1,编写native函数源码 c文件可以任意命名

#include "renwj_com_hellojni_JNIUtils.h"

JNIEXPORT jstring JNICALL Java_renwj_com_hellojni_JNIUtils_getStringFromNative
        (JNIEnv *env, jobject obj){
    return (*env)->NewStringUTF(env,"Hello jni");
}

注意:native函数的命名需要遵循一定的规范
2,在jni文件夹中创建可以为空的c文件和h文件,原因是google不允许只编译一个c文件
3,rebuild project 以获得so库。