日志
1日志
Logcat和ddms
1.1框架
Android日志框架是logger的内核模块
四个日志缓冲区:
Main应用程序的日志信息
Event系统事件
Radioradio相关日志
System低级系统调试信息
1.2原生日志api
为了便于原生代码向logger发送日志信息,在头文件log.h中定义
A需要包含头文件#include<android.h>
B修改android.mkLOCAL_LALIBS+=-llog
日志消息
包含以下几个字段:
Priority:verbosedebuginfowarningerrorfatal表示优先级
typedefenumandroid_LogPriority{
ANDROID_LOG_UNKNOWN=0,
ANDROID_LOG_DEFAULT,/*onlyforSetMinPriority()*/
ANDROID_LOG_VERBOSE,
ANDROID_LOG_DEBUG,
ANDROID_LOG_INFO,
ANDROID_LOG_WARN,
ANDROID_LOG_ERROR,
ANDROID_LOG_FATAL,
ANDROID_LOG_SILENT,/*onlyforSetMinPriority();mustbelast*/
}android_LogPriority;
Tag:logcat和ddms通过此标签对日志进行过虑
Message:存实际的日志信息
日志函数
_android_log_write:生成简单的日志消息
_android_log_write(ANDROID_LOG_WARN,”hello-jni”,”warninglog.”);
_android_log_print:生成格式化字符串作为日志消息
_andorid_log_print(ANDROID_LOG_ERROR,”hello-jni”,
”failedwitherrno%d”,erron);
_android_log_vprint:可以传递参数
_android_log_vprint(ANDROID_LOG_VERBOSS,”hello-jni”,format,args);
_android_log_assert:用于记录断言失败
_android_log_assert(“0!=errno”,”hello-jni”,”thereisanerror.”);
1.3受控制的日志
以hello-jni为例,在jni目录下添加my_log.h头文件
示例代码如下:
#pragmaonce
/**
*NDK基本日志框架
*
*@authorretacn
*
*/
#include<android/log.h>
/*定义日志优先级*/
#defineMY_LOG_LEVEL_VERBOSE1
#defineMY_LOG_LEVEL_DEBUG2
#defineMY_LOG_LEVEL_INFO3
#defineMY_LOG_LEVEL_WARNING4
#defineMY_LOG_LEVEL_ERROR5
#defineMY_LOG_LEVEL_FATAL6
#defineMY_LOG_LEVEL_SILENT7
#ifndefMY_LOG_TAG
#defineMY_LOG_TAG__FILE__
#endif
#ifndefMY_LOG_LEVEL
#defineMY_LOG_LEVELMY_LOG_LEVEL_VERBOSE
#endif
#defineMY_LOG_NOOP(void)0
#defineMY_LOG_PRINT(level,fmt,...)__android_log_print(level,MY_LOG_TAG,"(%s:%u)%s:"fmt,__FILE__,__LINE__,__PRETTY_FUNCTION__,##__VA_ARGS__)
#ifMY_LOG_LEVEL_VERBOSE>=MY_LOG_LEVEL
#defineMY_LOG_VERBOSE(fmt,...)MY_LOG_PRINT(ANDROID_LOG_VERBOSE,fmt,##__VA_ARGS__)
#else
#defineMY_LOG_VERBOSE(...)MY_LOG_NOOP
#endif
#ifMY_LOG_LEVEL_DEBUG>=MY_LOG_LEVEL
#defineMY_LOG_DEBUG(fmt,...)MY_LOG_PRINT(ANDROID_LOG_DEBUG,fmt,##__VA_ARGS__)
#else
#defineMY_LOG_DEBUG(...)MY_LOG_NOOP
#endif
#ifMY_LOG_LEVEL_INFO>=MY_LOG_LEVEL
#defineMY_LOG_INFO(fmt,...)MY_LOG_PRINT(ANDROID_LOG_INFO,fmt,##__VA_ARGS__)
#else
#defineMY_LOG_INFO(...)MY_LOG_NOOP
#endif
#ifMY_LOG_LEVEL_WARNING>=MY_LOG_LEVEL
#defineMY_LOG_WARNING(fmt,...)MY_LOG_PRINT(ANDROID_LOG_WARN,fmt,##__VA_ARGS__)
#else
#defineMY_LOG_WARNING(...)MY_LOG_NOOP
#endif
#ifMY_LOG_LEVEL_ERROR>=MY_LOG_LEVEL
#defineMY_LOG_ERROR(fmt,...)MY_LOG_PRINT(ANDROID_LOG_ERROR,fmt,##__VA_ARGS__)
#else
#defineMY_LOG_ERROR(...)MY_LOG_NOOP
#endif
#ifMY_LOG_LEVEL_FATAL>=MY_LOG_LEVEL
#defineMY_LOG_FATAL(fmt,...)MY_LOG_PRINT(ANDROID_LOG_FATAL,fmt,##__VA_ARGS__)
#else
#defineMY_LOG_FATAL(...)MY_LOG_NOOP
#endif
#ifMY_LOG_LEVEL_FATAL>=MY_LOG_LEVEL
#defineMY_LOG_ASSERT(expression,fmt,...)if(!(expression)){__android_log_assert(#expression,MY_LOG_TAG,fmt,##__VA_ARGS__);}
#else
#defineMY_LOG_ASSERT(...)MY_LOG_NOOP
#endif
增加日志
A原生代码中添加头文件
#include“my-log.h”
B在原生代码中添加日志声明语句
示例代码如下:
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI(JNIEnv*env,
jobjectthiz)
{
MY_LOG_VERBOSE("ThestringFormJNIiscalled!");
MY_LOG_DEBUG("env=%pthiz=%p",env,thiz);
MY_LOG_ASSERT(0!=env,"JniEnvcannotbeNULL");
MY_LOG_INFO("Returninganewstring");
return(*env)->NewStringUTF(env,"HellofromJNI!");
}
C更新android.mk
MY_LOG_TAG=\”hell-jni\”
Ifeq($(APP_OPTIM),release)
MY_LOG_LEVEL:=MY_LOG_LEVEL_ERROR
Else
MY_LOG_LEVEL:=MY_LOG_LEVEL_VERBOSE
Endif
LOCAL_CFLAGS+=-DMY_LOG_TAG=$(MY_LOG_TAG)
LOCAL_CFLAGS+=-DMY_LOG_LEVEL-$(MY_LOG_LEVEL)
LOCAL_LDLIBS+=-llog
LOCAL_PATH:=$(callmy-dir)
include$(CLEAR_VARS)
LOCAL_MODULE:=hello-jni
LOCAL_SRC_FILES:=hello-jni.c
#定义日志标签
MY_LOG_TAG:=\"hell-jni\"
#定义默认日志等级
ifeq($(APP_OPTIM),release)
MY_LOG_LEVEL:=MY_LOG_LEVEL_ERROR
else
MY_LOG_LEVEL:=MY_LOG_LEVEL_VERBOSE
Endif
#追加编译标记
LOCAL_CFLAGS+=-DMY_LOG_TAG=$(MY_LOG_TAG)
LOCAL_CFLAGS+=-DMY_LOG_LEVEL=$(MY_LOG_LEVEL)
#动态链接日志库
LOCAL_LDLIBS+=-llog
include$(BUILD_SHARED_LIBRARY)
注:在直接复制return(*env)->NewStringUTF(env,"HellofromJNI!");
函数时eclips会提示报错,修正办法是将以上代码改为: