Android studio 版本: Android Studio 2.0 Beta 6.0
Gradle 版本:gradle-2.10
NDK 版本:android-ndk-r10e

  1. 创建一个空项目
    ![](Android studio 下使用JNI/project.png)
  2. 打开Setting 在 Setting中设置NDK的路径:
    ![](Android studio 下使用JNI/setNDK.png)
  3. 添加Native代码,以及LoadLibrary,由于这里还没生成这些所以还是显示错误的,但是不要管它。
    ![](Android studio 下使用JNI/native.png)
  4. 点击Build-> make project 编译项目:
    ![](Android studio 下使用JNI/makepro.png)
    这时候会在,[项目名]/app/build/intermediates/classes/debug/com/idealist/testjniusage 下产生编译出来的class文件
    进入到[项目名]/app/src/main 目录下,运行如下javah命令:
    ![](Android studio 下使用JNI/path.png)
    javah -d jni -classpath /home/jimmy/Dev/sdk_m/sdk/platforms/android-23/android.jar:/home/jimmy/Dev/sdk_m/sdk/extras/android/support/v7/appcompat/libs/android-support-v4.jar:/home/jimmy/Dev/sdk_m/sdk/extras/android/support/v7/appcompat/libs/android-support-v7-appcompat.jar:/home/jimmy/GitHub_Opensrc/TestJNIUsage/app/build/intermediates/classes/debug/ com.idealist.testjniusage.MainActivity
    这时候会在项目目录树下产生一个jni的文件夹,如下图所示:
    ![](Android studio 下使用JNI/protree.png)

打开生成的头文件可以看到如下内容:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_idealist_testjniusage_MainActivity */

#ifndef _Included_com_idealist_testjniusage_MainActivity
#define _Included_com_idealist_testjniusage_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
#undef com_idealist_testjniusage_MainActivity_BIND_ABOVE_CLIENT
#define com_idealist_testjniusage_MainActivity_BIND_ABOVE_CLIENT 8L
#undef com_idealist_testjniusage_MainActivity_BIND_ADJUST_WITH_ACTIVITY
#define com_idealist_testjniusage_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L
#undef com_idealist_testjniusage_MainActivity_BIND_ALLOW_OOM_MANAGEMENT
#define com_idealist_testjniusage_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
#undef com_idealist_testjniusage_MainActivity_BIND_AUTO_CREATE
#define com_idealist_testjniusage_MainActivity_BIND_AUTO_CREATE 1L
#undef com_idealist_testjniusage_MainActivity_BIND_DEBUG_UNBIND
#define com_idealist_testjniusage_MainActivity_BIND_DEBUG_UNBIND 2L
#undef com_idealist_testjniusage_MainActivity_BIND_IMPORTANT
#define com_idealist_testjniusage_MainActivity_BIND_IMPORTANT 64L
#undef com_idealist_testjniusage_MainActivity_BIND_NOT_FOREGROUND
#define com_idealist_testjniusage_MainActivity_BIND_NOT_FOREGROUND 4L
#undef com_idealist_testjniusage_MainActivity_BIND_WAIVE_PRIORITY
#define com_idealist_testjniusage_MainActivity_BIND_WAIVE_PRIORITY 32L
#undef com_idealist_testjniusage_MainActivity_CONTEXT_IGNORE_SECURITY
#define com_idealist_testjniusage_MainActivity_CONTEXT_IGNORE_SECURITY 2L
#undef com_idealist_testjniusage_MainActivity_CONTEXT_INCLUDE_CODE
#define com_idealist_testjniusage_MainActivity_CONTEXT_INCLUDE_CODE 1L
#undef com_idealist_testjniusage_MainActivity_CONTEXT_RESTRICTED
#define com_idealist_testjniusage_MainActivity_CONTEXT_RESTRICTED 4L
#undef com_idealist_testjniusage_MainActivity_MODE_APPEND
#define com_idealist_testjniusage_MainActivity_MODE_APPEND 32768L
#undef com_idealist_testjniusage_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING
#define com_idealist_testjniusage_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L
#undef com_idealist_testjniusage_MainActivity_MODE_MULTI_PROCESS
#define com_idealist_testjniusage_MainActivity_MODE_MULTI_PROCESS 4L
#undef com_idealist_testjniusage_MainActivity_MODE_PRIVATE
#define com_idealist_testjniusage_MainActivity_MODE_PRIVATE 0L
#undef com_idealist_testjniusage_MainActivity_MODE_WORLD_READABLE
#define com_idealist_testjniusage_MainActivity_MODE_WORLD_READABLE 1L
#undef com_idealist_testjniusage_MainActivity_MODE_WORLD_WRITEABLE
#define com_idealist_testjniusage_MainActivity_MODE_WORLD_WRITEABLE 2L
#undef com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_DIALER
#define com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_DIALER 1L
#undef com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_DISABLE
#define com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_DISABLE 0L
#undef com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL
#define com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
#undef com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL
#define com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
#undef com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_SHORTCUT
#define com_idealist_testjniusage_MainActivity_DEFAULT_KEYS_SHORTCUT 2L
#undef com_idealist_testjniusage_MainActivity_RESULT_CANCELED
#define com_idealist_testjniusage_MainActivity_RESULT_CANCELED 0L
#undef com_idealist_testjniusage_MainActivity_RESULT_FIRST_USER
#define com_idealist_testjniusage_MainActivity_RESULT_FIRST_USER 1L
#undef com_idealist_testjniusage_MainActivity_RESULT_OK
#define com_idealist_testjniusage_MainActivity_RESULT_OK -1L
#undef com_idealist_testjniusage_MainActivity_HONEYCOMB
#define com_idealist_testjniusage_MainActivity_HONEYCOMB 11L
#undef com_idealist_testjniusage_MainActivity_MSG_REALLY_STOPPED
#define com_idealist_testjniusage_MainActivity_MSG_REALLY_STOPPED 1L
#undef com_idealist_testjniusage_MainActivity_MSG_RESUME_PENDING
#define com_idealist_testjniusage_MainActivity_MSG_RESUME_PENDING 2L
/*
* Class: com_idealist_testjniusage_MainActivity
* Method: getNativeString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_idealist_testjniusage_MainActivity_getNativeString
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
  1. 创建对应的源码文件如下: 很简单就是返回一个Hello From JNI!字符串。
#include <jni.h>
#include <android/log.h>
#ifndef LOG_TAG
#define LOG_TAG "ANDROID_LAB"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif
#ifndef _Included_com_idealist_testjniusage_MainActivity
#define _Included_com_idealist_testjniusage_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: lab_sodino_jnitest_MainActivity
* Method: getStringFromNative
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_idealist_testjniusage_MainActivity_getNativeString
(JNIEnv * env, jobject jObj){
return (*env)->NewStringUTF(env,"Hello From JNI!");
}

#ifdef __cplusplus
}
#endif
#endif

点击运行按钮,这时候很有可能会出现如下的错误:
![](Android studio 下使用JNI/ndkbug.png)
这个问题很简单其实上面已经给出解决方案了,就是在gradle.property这个文件下添加如下配置:
![](Android studio 下使用JNI/fixed.png)

6.修改Module 下的 gradle.build

apply plugin: 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.1"

defaultConfig {
applicationId "com.idealist.testjni"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
//这里是新增加的
ndk {
moduleName "Testjni" //这个是LoadLibary 参数相同的名字
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
//ldLibs "log", "z", "m" //链接时使用到的库,对应LOCAL_LDLIBS
//cFlags 编译gcc的flag,对应LOCAL_CFLAGS
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//这里是新增加的,用于支持JNIdebug的
ndk {
debuggable = true
}
}
debug {
//这里是新增加的,用于支持JNIdebug的
debuggable = true
jniDebuggable = true
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:design:23.1.0'
}

  1. 点击运行。
    在手机上就可以看到如下的界面了:

    ![](Android studio 下使用JNI/result.png)

可能长期被eclipse虐惯的人会问了,不用写mk吗?是不用写了,其实在bradle.build上面已经做了类似的工作,这个mk文件会根据你的配置在output 目录下生成,包括各个平台的库文件都会在这个目录下生成,如下图所示:
![](Android studio 下使用JNI/output.png)

下面是生成的mk文件内容:
![](Android studio 下使用JNI/mk.png)

Demo可以在如下地址进行下载:
Demo Github

Contents