操作系统是win10,开发使用的IDE工具是android Studio,用Android Studio进行NDK开发比Eclipse更加灵活方便,不需要再修改makefile文件,也不需要像以前一样下载Cygwin。我选择直接在SDK manager中下载NDK,当然也可以直接在android.developer的NDK中按照步骤下载安装NDK,具体网址见:
http://developer.android.com/tools/sdk/ndk/index.html#GetStartedAndroid NDK官网下载
一、下载NDK
检查AndroidStudio的版本,我使用的最新的1.5,好像1.3之后在Android 环境开发JNI程序搭建开发环境变得相对简单了,可以使用新的Gradle构建工具配置NDK环境.
使用AS内置的SDK Manager下载NDK(我的电脑可以下载,但是有的好像说是被墙了还是什么原因下不了),在SDK Tools下有一个androidNDK选项,一般是没有打勾的,勾上再apply,或者在项目上右键打开Project Structure,切到的SDK Location页在的androidNDKLocation,有一个提示安装,点击即可进行安装。安装好后,将安装路径复制在androidNDKLocation下。
二、设置好NDK后,开始设置Gradle。要修改的文件有三个。(这里面好多坑,出了几个小问题,结果搞了一晚上)
主要分为以下三个步骤:
A、首先设置projectGradle:
将该文件中的dependencies{}块中的gradle替换为实验性质的gradle:
classpath 'com.android.tools.build:gradle-experimental:0.4.0'
这里选择的0.4.0的gradle,后面的wrapper,要设置为gradle-2.8-all,具体的见第三步。
B、再设置moduleGradle,这个修改比较多,千万看清楚:
apply plugin: 'com.android.model.application'
model{
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.1"
defaultConfig.with {
applicationId = "com.example.vivien_shaw.ndktest"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
tasks.withType(JavaCompile) {
// 指定编译JDK版本
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
}
android.ndk {
moduleName = "test"
// ldLibs +="log"
// abiFilters +="armeabi"
// abiFilters +="armeabi-v7a"
// abiFilters +="x86"
cppFlags.add("-std=c++11")
ldLibs.addAll(['android', 'log', 'OpenSLES'])
stl = "gnustl_static"
}
android.buildTypes {
release {
minifyEnabled = false
proguardFiles.add(file('proguard-android.txt'))
//proguardFiles += file( 'proguard-rules.pro')
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.0.1'
}
里面注释掉的内容就是我修改过的地方,分别说明一下:
在android.ndk中,注释掉了所谓支持armeabi,armeabi-v7a,x86三个平台这三条语句,而修改为android官方的ndk实例中module.gradle对应模块的语句。如果不修改就会报这个错:
还有就是dependencies{}中的compile 'com.android.support:design:23.0.1' 这里需要添加上这句话,而且后面的版本号要和前面的相同。
和自动生成的gradle相比,更改的有以下几个地方:
1、第一行android.application中加入了module
2、除dependenceies以外的部分被module模块包装了起来
3、defaultConfig{} 需要写成defaultConfig.with{} 的形式
4、buildTypes 需要从android{} 中取出来,写成android.buildTypes{}的形式
5、android{}中多出了tasks.withType(JavaCompile).(我也看到有的博客里面添加compileOptions.with
{},并且放在adroid{}外的这种方式,不知道行不行)
6、module{}中添加android.ndk{}模块
还要一些需要注意的地方:
1、所有值的设置都要写成 xxx = yyyy的形式,比如: applicationId = "com.zyp.ndktest" (自动生成的gradle 则可能是: applicationId "com.zyp.ndktest" ),否则会爆这种错误:Error:Cause: org.gradle.api.internal.ExtensibleDynamicObject, 当出现此类错误,检查是否都用了 “=”的方式。
2、自动生成的buildType也需要修改:proguardFiles += file('proguard-rules.pro'
)
3、minSdkVersion和targetSdkVersion 后都需要加上apiLevel
4、增加compileOptions.with{} 需要选择JavaVersion.VERSION_1_7,否则会报这种错误:Bad class file magic or version
C、最后设置gradleWrapper:
将左边的工程视图调整到Project,在gradle->wrapper->grale-wrapper.properties文件的最后设置:distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip,注意这里如果在Project gradle中设置的是gradle-experimental:0.4.0,则这里选择gradle-2.8-all,如果是gradle-experimental:0.2.0,需要设置gradle-2.5-all,由于我这里没有2.5版本的gradle,所以我选择了2.8。
最后按这个键确认三个文件修改的正确,修改正确的话,将会在gradle中显示BUILD SUCCESSFUL
三、增加JNI目录
见下图,回到project视图,在main下新建一个JNI folder,如图:
在main/java下新建一个Test类,内容如下:
package com.example.vivien_shaw.ndktest;
/**
* Created by vivien_shaw on 2016/3/11.
*/
public class Test {
static {
System.loadLibrary("test");
}
public native void test();
}
这时你就会发现test显示为红色的,将鼠标放在上面,alt+enter键将会出现 Creat function java_com……等字样的提示,点击自动在之前新建的jni下出现对应的.c文件,文件内容添加为:
JNIEXPORT void JNICALL
Java_com_example_vivien_1shaw_ndktest_Test_test(JNIEnv *env, jobject instance) {
// TODO
__android_log_write(ANDROID_LOG_ERROR,"TAG","TEST");
}
哦对了,我自己操作的时候在这里出现了一个问题,当我按下alt+enter键之后,没有出现creat function等字样的提示,而是告诉我:cannot resolve corresponding jni function ,后来我发现是我前面的三个文件配置出错导致gradle不能同步,修改正确之后就好了。
使用命令行即可生成对应的H文件,这里我用的android studio下的terminal,当用cmd时生成不出来,具体原因还不清楚:
这里我加了一句话,-classpath D:\learning_program\SDK\platforms/android-23\android.jar;..\..\build\intermediates\classes\debug 具体原因见此说明:http://www.th7.cn/Program/Android/201509/550864.shtml
点击打开链接
之后会在jni目录生成对应的头文件,最后在mainActivicity中加入一下内容:
Test t=new Test();
t.test();
运行,就会看到logcat的内容: