1. java层
java层打印log由类android.util.Log类实现,该类定义于文件:
frameworks/base/core/java/android/util/Log.java (APP 框架层)
对应的JNI层代码在文件:frameworks/base/core/jni/android_util_Log.cpp (本地框架层)
这个层次主要调用了HAL层的liblog库中的函数__android_log_buf_write() --> write_to_log() -->
__write_to_log_kernel() --> log_writev() (这些函数都处于库liblog中: system/core/liblog)。
这样在上层java中只要包含了类android.util.Log,都可以使用Log.v, Log.d, Log.i来打印log。
其实,android编译版本可以根据TARGET_BUILD_TYPE等于debug或者release来打开和屏蔽掉log信息,但是这必须得有个前提,
就是我们在上层调用Log.d等函数的时候需要按照如下格式来写即可:
static boolean DEBUG = true && Config.DEBUG;
if(DEBUG)
Log.d(TAG, "storeMessage " + this.toString());
这里实际上是可以直接用if(Config.DEBUG)的,但是为了能够我们自己控制这个log的输出的话,建议使用上面的方式。比如在debug版本
的时候,我们就可以通过flase && Config.DEBUG来去掉这些log输出。
Config类的实现在文件:frameworks/base/core/java/android/util/Config.java,其中将会引用类ConfigBuildFlags,这个类是在
目录:frameworks/base/core/config/ - debug、ndebug、sdk目录,到底使用哪一个目录下的ConfigBuildFlags定义,需要取决于
TARGET_BUILD_TYPE的定义:(这个config目录下还有一个readme文件,可以读读,会有帮助的)
One of the subdirectories {debug, ndebug} is included in framework.jar by http://www.cnblogs.com/Android.mk depending on the value of
$(TARGET_BUILD_TYPE).
那就来看一下http://www.cnblogs.com/Android.mk这个文件中如何决定的:
frameworks/base/Android.mk
# Include a different set of source files when building a debug build.
# TODO: Maybe build these into a separate .jar and put it on the classpath
# in front of framework.jar.
# NOTE: Do not use this as an example; this is a very special situation.
# Do not modify LOCAL_SRC_FILES based on any variable other
# than TARGET_BUILD_TYPE, otherwise builds can become inconsistent.
ifeq ($(TARGET_BUILD_TYPE),debug)
LOCAL_SRC_FILES += $(call find-other-java-files,core/config/debug)
else
LOCAL_SRC_FILES += $(call find-other-java-files,core/config/ndebug)
endif
这里就是通过TARGET_BUILD_TYPE来选择将那个目录下的ConfigBuildFlags定义编译进framework.jar。
编译android的时候可以通过这两个宏来进行组合:TARGET_BUILD_VARIANT 和TARGET_BUILD_TYPE
TARGET_BUILD_VARIANT: user userdebug eng tests (默认eng)
TARGET_BUILD_TYPE: debug release (默认release)
这两个宏可以定义在文件buildspec.mk下,也可以直接加载make命令中,也可以使用. build/envsetup.sh之后使用choosevariant来选择。
对java层log输出的实现修改:
lizhiguo@informax-ui1:~/new_hope/alps/frameworks/base/core/jni$ svn diff android_util_Log.cpp
Index: android_util_Log.cpp
===================================================================
--- android_util_Log.cpp (revision 510)
+++ android_util_Log.cpp (working copy)
@@ -79,9 +79,12 @@
static int toLevel(const char* value)
{
switch (value[0]) {
- case 'V': return levels.verbose;
- case 'D': return levels.debug;
- case 'I': return levels.info;
+ case 'V': return -1; // lizhiguo 2011-07-19
+ //case 'V': return levels.verbose;
+ //case 'D': return levels.debug;
+ //case 'I': return levels.info;
+ case 'D': return -1;
+ case 'I': return -1;
case 'W': return levels.warn;
case 'E': return levels.error;
case 'A': return levels.assert;
@@ -165,7 +168,9 @@
tag = env->GetStringUTFChars(tagObj, NULL);
msg = env->GetStringUTFChars(msgObj, NULL);
- int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
+ int res = 1; /* lizhiguo 2011-07-19, for release sofe */
+ if( (priority != 2) && (priority != 3) && (priority != 4) )
+ res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
if (tag != NULL)
env->ReleaseStringUTFChars(tagObj, tag);
2. 中间层(HAL+JNI)
JNI层代码需包含头文件frameworks/base/include/utils/Log.h,实际上这个头文件include了HAL层代码使用的头文件system/core/include/cutils/log.h
在相应的中间层代码中包含log TAG的地方,使用如下形式:
//#define NDEBUG
#define LOG_NDEBUG 1
#define LOG_TAG "RFID_HAL"
#include <cutils/log.h>
下面是关于HAL层log的屏蔽代码:主要是去掉V、D、I等级的log输出:
lizhiguo@informax-ui1:~/new_hope/alps$ svn diff system/core/include/cutils/log.h
Index: system/core/include/cutils/log.h
===================================================================
--- system/core/include/cutils/log.h (revision 510)
+++ system/core/include/cutils/log.h (working copy)
@@ -51,6 +51,8 @@
* You can modify this (for example with "#define LOG_NDEBUG 0"
* at the top of your source file) to change that behavior.
*/
+#define LOG_NDEBUG 1 /* lizhiguo 2011-07-19, for release sofe*/
+
#ifndef LOG_NDEBUG
#ifdef NDEBUG
#define LOG_NDEBUG 1
@@ -98,29 +100,45 @@
* Simplified macro to send a debug log message using the current LOG_TAG.
*/
#ifndef LOGD
+#if LOG_NDEBUG /* lizhiguo 2011-07-19, for release sofe*/
+#define LOGD(...) ((void)0)
+#else
#define LOGD(...) ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
+#endif
#ifndef LOGD_IF
+#if LOG_NDEBUG
+#define LOGD_IF(cond, ...) ((void)0)
+#else
#define LOGD_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#endif
+#endif
/*
* Simplified macro to send an info log message using the current LOG_TAG.
*/
#ifndef LOGI
+#if LOG_NDEBUG /* lizhiguo 2011-07-19, for release sofe*/
+#define LOGI(...) ((void)0)
+#else
#define LOGI(...) ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
#endif
+#endif
#ifndef LOGI_IF
+#if LOG_NDEBUG
+#define LOGI_IF(cond, ...) ((void)0)
+#else
#define LOGI_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#endif
+#endif
/*
* Simplified macro to send a warning log message using the current LOG_TAG.
@@ -169,16 +187,24 @@
* debug priority.
*/
#ifndef IF_LOGD
+#if LOG_NDEBUG /* lizhiguo 2011-07-19, for release sofe*/
+#define IF_LOGD() if (false)
+#else
#define IF_LOGD() IF_LOG(LOG_DEBUG, LOG_TAG)
#endif
+#endif
/*
* Conditional based on whether the current LOG_TAG is enabled at
* info priority.
*/
#ifndef IF_LOGI
+#if LOG_NDEBUG /* lizhiguo 2011-07-19, for release sofe*/
+#define IF_LOGI() if (false)
+#else
#define IF_LOGI() IF_LOG(LOG_INFO, LOG_TAG)
#endif
+#endif
/*
* Conditional based on whether the current LOG_TAG is enabled at
@@ -227,29 +253,45 @@
* Simplified macro to send a debug system log message using the current LOG_TAG.
*/
#ifndef SLOGD
+#if LOG_NDEBUG /* lizhiguo 2011-07-19, for release sofe*/
+#define SLOGD(...) ((void)0)
+#else
#define SLOGD(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
+#endif
#ifndef SLOGD_IF
+#if LOG_NDEBUG
+#define SLOGD_IF(cond, ...) ((void)0)
+#else
#define SLOGD_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#endif
+#endif
/*
* Simplified macro to send an info system log message using the current LOG_TAG.
*/
#ifndef SLOGI
+#if LOG_NDEBUG /* lizhiguo 2011-07-19, for release sofe*/
+#define SLOGI(...) ((void)0)
+#else
#define SLOGI(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#endif
+#endif
#ifndef SLOGI_IF
+#if LOG_NDEBUG
+#define SLOGI_IF(cond, ...) ((void)0)
+#else
#define SLOGI_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) \
: (void)0 )
#endif
+#endif
/*
* Simplified macro to send a warning system log message using the current LOG_TAG.
3. c代码
对于c代码,为了更好更容易地控制log输出,在每个模块中单独定义print语句时,最好在全局控制宏的控制之下来定义。
#define C_PRINTF_CONTROL
模块中定义:
#define CUSTOM_DEF_TPD
#ifdef C_PRINTF_CONTROL
#ifdef CUSTOM_DEF_TPD
#define TPD_DEBUG(a,arg...) printk(TPD_DEVICE ": " a,##arg)
#else // CUSTOM_DEF_TPD
#define TPD_DEBUG(arg...)
#endif // CUSTOM_DEF_TPD
#else // C_PRINTF_CONTROL
#define TPD_DEBUG(arg...)
#endif // C_PRINTF_CONTROL