我的博客:http://blog.csdn.net/muyang_ren
Google的github示例代码 :https://github.com/googlesamples/android-ndk
一、配置JNI开发环境
软件环境
JAVA JDK: jdk1.8.0_60
Android studio版本:1.5
注:Android Studio 1.3版本以上才支持gradle构建JNI
1、使用Android Studio下载NDK
2、修改gradle
默认情况下(2)是不用改的
(1)修改gradle目录下的build.gradle
classpath 'com.android.tools.build:gradle-experimental:0.4.0'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
//classpath 'com.android.tools.build:gradle:1.5.0'
classpath 'com.android.tools.build:gradle-experimental:0.4.0'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
(2)修改gradle/gradle-wrapper.properties中的版本修改为2.8
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
#Wed Oct 21 11:34:03 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
(3)修改app/build.gradle(大改动)
1、apply plugin: ‘com.android.application’ 改成 apply plugin: ‘com.android.model.application’
2、语法结构
1) android语句由model包裹。
2)原来在android里面的buildTypes转在model属性下
3)dependencies属性依然独立在外
3、 各项配置都是有等号“ = ”赋值的
没改时的build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "com.example.lianghuiyong.test"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
改成
apply plugin: 'com.android.model.application'
model{
android {
compileSdkVersion = 23
buildToolsVersion = "23.0.2"
defaultConfig.with {
applicationId = "com.example.lianghuiyong.myjni"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
}
android.buildTypes {
release {
minifyEnabled = false
//proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
proguardFiles.add(file('proguard-rules.txt'))
}
}
android.ndk {
// moduleName = "hello-jni"
CFlags.add("-std=c99")
ldLibs.addAll(["android","OpenSLES", "log"]) //加Log支持
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
}
【windows 10 使用备注】
1、NDK目录路径不得大于三层
2、c盘的权限高,请放置其他盘
ndk.dir=D\:\\Android\\sdk\\ndk-bundle
sdk.dir=D\:\\Android\\sdk
错误笔记
错误1
Error:Cause: org.gradle.api.internal.ExtensibleDynamicObject
./app/build.gradle文件修改时请注意赋值要带等号“ = ”
错误2
Error:Unable to load class ‘com.android.build.gradle.managed.ProductFlavor_Impl’.
Possible causes for this unexpected error include:
defaultConfig{
applicationId = "com.example.lianghuiyong.myjni"
minSdkVersion = 15
targetSdkVersion = 23
versionCode = 1
versionName = "1.0"
}
应改成
defaultConfig.with {
applicationId = "com.example.lianghuiyong.myjni"
minSdkVersion.apiLevel = 15
targetSdkVersion.apiLevel = 23
versionCode = 1
versionName = "1.0"
}
错误3
Error:No signature of method: org.gradle.model.ModelMap.getDefaultProguardFile() is applicable for argument types: (java.lang.String) values: [proguard-android.txt]
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
改成
proguardFiles.add(file('proguard-rules.txt'))
二、编写JNI
1、新建JNI目录
2、库文件申明(test-jni是库名也是c文件名,生成的JNI文件名libtest-jni.so)
1)在app/build.gradle下的android.ndk 内添加 moduleName = “test-jni”
android.ndk {
......
moduleName = "test-jni"
......
}
2)在所需的activity下加载所需的JNI库
public class MainActivity extends AppCompatActivity {
......
static {
System.loadLibrary("test-jni");
}
......
}
3)在所需的activity下声明一个native方法
public class MainActivity extends AppCompatActivity {
......
public native String hellojni();
......
}
声明的native函数应该是红色报错的,坐标落在函数上,按ALT+Enter,选中,会自动在jni文件夹下新建test-jni.c,并创建hellojni方法:Java_com_example_lianghuiyong_myapplication_MainActivity_hellojni,前面一长串是包名+类名+方法名。
test-jni.c
#include <jni.h>
JNIEXPORT jstring JNICALL
Java_com_example_lianghuiyong_myapplication_MainActivity_hellojni(JNIEnv *env, jobject instance) {
// TODO
//hellojni();返回“hello jni”字符串
return (*env)->NewStringUTF(env, "hello jni");
}
编译后可生成这些平台使用的库文件
JNI 打印Log
1、修改app/build.gradle
android.ndk{
moduleName = "timecount-jni"
CFlags.add("-std=c99")
ldLibs.addAll(["android","OpenSLES", "log"]) //加Log支持
}
2、JNI中加头文件
#include <android/log.h>
//使用实例
#define TAG "lhy"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
LOGD("JNI:h = %d; m = %d; s = %d;",h,m,s);
JNI具体讲解可参见:http://blog.csdn.net/innost/article/details/47204557