Android Java/C 日志输出

  1. 1. java层
  2. 2. 中间层(HAL+JNI)
  3. 3. c代码

@link
http://www.cnblogs.com/hoji-real/articles/2609756.html

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等函数的时候需要按照如下格式来写即可:

1
2
3
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

1
2
3
4
5
6
7
8
9
10
11
# 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

===================================================================
--- 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的地方,使用如下形式:

1
2
3
4
//#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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

===================================================================
--- 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语句时,最好在全局控制宏的控制之下来定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
#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

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wilber_bai@hotmail.com

文章标题:Android Java/C 日志输出

文章字数:1,570

本文作者:风沉殇史

发布时间:2017-12-12, 12:12:12

最后更新:2018-06-21, 16:20:40

原始链接:http://wilber.win/posts/7e74f090/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏