在写jni代码时,不可避免的需要调试代码,而c端的代码,又无法断点调试这就要求我们必须在cpp文件中打印语句供我们判断code的正确与否,但是你真这么做了会发现,不论是在as的控制台还是adb抓出来的log文件,我们写好的输出语句无法显示(printf、cout都试试),不必怀疑code有误,它是正确的,但就是打印不出来,搜索发现大多数人告诉你:需要在Android.mk中加入LOCAL_LDLIBS+= -L$(SYSROOT)/usr/lib -llog ,
- 这个本身是对的,但是这是在eclipse开发时的操作,as它不这么用,你会发现你设置了并没鸟用
- 更可怕的是,as里没有Android.mk文件 因为as里现在都是使用cmake来编译ndk,build.gradle会直接链接到cmakelists.txt,由它来掌控jni的编译。那怎么办?
cmake当然不会傻傻的告诉你jni的log不能打印,其实是我们自己没有设置正确,下面来看正常的打开方式:
很显然没有Android.mk, as的build.gradle必然是核心中的核心,在jni的module模块build.gradle文件中,加入这样一句声明:
android{
ndk{
ldLibs "log" //实现__android_log_print
abiFilters "arm64-v8a", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库。
}
}
在cpp文件中,
#include <string.h>
#include <android/log.h>
#include <jni.h>
#include <stdio.h>
#define LOG_TAG "native-dev"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
jint getBackTotalNum(JNIEnv * env,jobject job,jint x,jint y){
LOGI("getBackTotalNum,x is :%d,y is :%d",x,y);
return x+y;
}
这样就能打印出来log了吗?正常情况是可以的(在玩demo的时候),因为你的cmakelists文件里只会生成一个so,但实际开发的时候,我可能生成20个so,链接了很多的cpp文件,这时候cmakelists会庞大无比,你就可能忘了给某个so链接log,下面给出链接log,只要这个so库中需要打印log,必须一对一的target_link_libraries这个log库,
add_library(linkJNI SHARED src/main/cpp/launchScan.cpp)
find_library( log-lib log )
target_link_libraries(linkJNI ${log-lib} )