最近在as上捣鼓了一下jni,参考别人的做法,全都是getStringFromC这个案例。看似挺简单却还是遇见一些奇葩困难。
环境: xp 32位+as2.1.2+ndk r10
项目demo记录:http://download.csdn.net/detail/kernel_/9594810
demo可以实现jni的调用以及控制台打印log
as莫名其妙 报错。主要原因是开发环境影响,如下:
make.exe: *** No rule to make target Error:Execution failed for task ':app:compileDebugNdk'. > com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'D:\ndk\android-ndk32-r10-windows-x86\android-ndk-r10\ndk-build.cmd'' finished with non-zero exit value 2 D:\MyApplication\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/NdkJniDemo/D_\MyApplication\app\src\main\jni', needed by `D:\MyApplication\app\build\intermediates\ndk\debug\obj/local/armeabi/objs/NdkJniDemo/D_\MyApplication\app\src\main\jni\cc.o'. Stop.
据说是android studio的bug 解决方法:在jni文件夹添加一个.c或者.cpp文件
2.
ndk版本
解决方法:
android-ndk-r9d-windows-x86
改为
android-ndk32-r10-windows-x86
gradle配置:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.administrator.myapplication"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName "NdkTest" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。}
ldLibs "log"
}
}
sourceSets {
main {
jni.srcDirs = ['src/main/jni']//jni源码时使用
//jniLibs.srcDirs = ['libs'] //so库时使用
}
}
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.4.0'
}
生成的so库:在app\build\intermediates\ndk......
拷贝进libs目录,引用方法:gradle添加
sourceSets {
main {
jni.srcDirs = ['src/main/jni']//jni源码时使用
//jniLibs.srcDirs = ['libs'] //so库时使用
}
}
log打印:gradle添加ldLibs "log"
ndk {
moduleName "NdkTest" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。}
ldLibs "log"
}
C代码使用log:
#include <android/log.h>
#include "com_example_administrator_myapplication_JniUtils.h"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "DEBUG", __VA_ARGS__)
/*
* Class: Java_com_wobiancao_ndkjnidemo_ndk_JniUtils
* Method: getStringFormC
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_administrator_myapplication_JniUtils_getStringFormC
(JNIEnv *env, jobject obj){
/**
* __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,“***”) // LOG类型:debug
__android_log_print(ANDROID_LOG_INFO,LOG_TAG,“***”) // LOG类型:info
__android_log_print(ANDROID_LOG_WARN,LOG_TAG,“***”) // LOG类型:warning
__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,“***”) // LOG类型:error
__android_log_print(ANDROID_LOG_FATAL,LOG_TAG,“***”) // LOG类型:Verbose???
*/
LOGE("定义的错误信息打印");
__android_log_print(ANDROID_LOG_ERROR,"---打印--","ANDROID_LOG_ERROR");
__android_log_print(ANDROID_LOG_INFO, "---打印---","ANDROID_LOG_INFO");
return (*env)->NewStringUTF(env,"from c");}
输出效果: