Android Studio2.1上C++开发(一)——第一个JNI程序

说明

Eclipse上进行NDK开发需要编写Android.mk文件和Application.mk文件。Android Studio上也可编写Android.mk和Application.mk文件,然后在Gradle中进行配置来进行NDK开发。但是也有更简单的方法来进行NDK开发。就是使用Gradle-experimental来构建项目。

工具

Android Studio2.12
NDK 12
Gradle-experimental-0.7.2

步骤

1、下载配置NDK。如图所示:

下载后在SDK文件夹中会出现ndk-bundle文件夹,这个就是ndk工具的目录了。
下载完成后需要配置ndk:

Android Studio2.1上C++开发(一)——第一个JNI程序_第1张图片

2、修改Project下的build.gradle文件:

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        //classpath 'com.android.tools.build:gradle:2.1.2'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
        classpath "com.android.tools.build:gradle-experimental:0.7.2"
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

gradle-experimental的版本可以自行选择,一般来说,选择最新的稳定版。最新版本可以在jcenter或者maven上查阅,基于你选择的仓库。当前(2016.07.09)在maven上最新的是0.7.2,jcenter上最新的是0.8.0-alpha5。

3、修改module下的build.gradle文件。

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

model{
    android {
        compileSdkVersion=23
        buildToolsVersion="23.0.3"

        defaultConfig.with {
            applicationId="edu.wuwang.study"
            minSdkVersion.apiLevel=9
            targetSdkVersion.apiLevel=23
            versionCode=1
            versionName="1.0"

        }

        buildTypes {
            release {
                minifyEnabled = false
                proguardFiles.add(file('proguard-rules.txt'))
            }
        }

    }

    android.ndk{
        moduleName="NdkJniTest"                    //生成的so名字
        cppFlags.add( "-std=c++11")
        cppFlags.add( "-fexceptions")
    }
}

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

需要注意的是apply plugin: 'com.android.model.application'不再是apply plugin: 'com.android.application'。否则会报错

Error:(1, 0) Plugin with id ‘com.android.application’ not found.
Open File

android{}外面添加model{}否则也会报错

Error:(3, 0) Gradle DSL method not found: ‘android()’
Possible causes:

  • The project ‘Study’ may be using a version of the Android Gradle plug-in that does not contain the method (e.g. ‘testCompile’ was added in 1.1.0).
    Fix plugin version and sync project
  • The project ‘Study’ may be using a version of Gradle that does not contain the method.
    Gradle settings
  • The build file may be missing a Gradle plugin.
    Apply Gradle plugin

另外还有其他的问题也需要注意,对照上面的配置进行修改原来的gradle文件。详细的说明参看gradle-experimental官方文档

4、进行C++开发。

在Android Studio中,jni默认的文件夹是src/main/jni。当然你也可以自己指定文件夹。在这个过程中,你需要编写JNI接口文件。如下所示:

package edu.wuwang.study.ndk;

/** * Created by DoggyCoder on 2016/7/8 0008. */
public class JniTest {

    static {
        System.loadLibrary("NdkJniTest");
    }

    public native String getTestString(int type);

}

然后利用Javah这个工具生成.h文件。打开Android Studio下的Terminal,进入module的build\intermediates\classes\debug文件夹:cd app/build/intermediates/classes/debug。然后生成.h:javah -classpath . -jni edu.wuwang.study.ndk.JniTest。下一步就是把.h文件拷贝到jni目录下,并编写cpp文件了。
生成的.h文件大致如下所示(和你的jni接口有关):

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

#ifndef _Included_edu_wuwang_study_ndk_JniTest
#define _Included_edu_wuwang_study_ndk_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/* * Class: edu_wuwang_study_ndk_JniTest * Method: getTestString * Signature: (I)Ljava/lang/String; */
JNIEXPORT jstring JNICALL Java_edu_wuwang_study_ndk_JniTest_getTestString
  (JNIEnv *env, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif

根据.h文件编写cpp文件:

//
// Created by Administrator on 2016/7/8 0008.
//
#include "edu_wuwang_study_ndk_JniTest.h"

JNIEXPORT jstring JNICALL Java_edu_wuwang_study_ndk_JniTest_getTestString
  (JNIEnv * env, jobject, jint){
    return env->NewStringUTF((char *)"Hello from JNI !");
  }

这里需要注意的是,这是C++的写法,C的写法和这个略有出入,主要是语法和方法的差异。这里不讨论。
这样就OK了,在其他地方像调用一般的类一样调用JNI接口类。点击运行即可。

工程结构

最后工程的结构如下所示:

你可能感兴趣的:(jni,NDK-C++)