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