配套系列教学视频链接:
? ? ??安卓系列教程之ROM系统开发-百问100ask
说明
系统:Android10.0
设备: FireFly RK3399 (ROC-RK3399-PC-PLUS)
前言
在编写代码时, 有不同的级别的日志, 有些日志需要在调试阶段看, 在运行时就不能出现, 此时就可以通过android提供的接口来进行控制日志的输出。
一, 编译时静态控制
#define? LOG_INFO 5
#define LOG_DEBUG 6
#define?current_dbg_level ?LOG_INFO
#define my_log(level, fmt, ...) ?\
do { \
if(current_dbg_level >= level) \
ALOGI(fmt, ##__VA_ARGS__); \
}while(0);
上面的代码主要是通过比对my_log(level, fmt, ...) 中level 和current_dbg_level的大小, 稍微注意的的是, LOG_INFO比LOG_DEBUG高, 但是此处设置的是数字越小界别越高。上面的代码特点是, 如果需要调整输出的日志级别,就需要重新改代码并编译,再运行才能起效。
二,运行时动态调整
Android系统其实提供了相关接口, 可以在不改代码的情况下, 通过命令来控制程序的日志级别输出, 这样就省去了编译的步骤,并为灵活输出日志提供了途径, 该接口提供java和C/C++的接口, 如下所示:
java接口:boolean isLoggable(string TAG, int? level)
解释:
1, 该函数是将参数中的level与默认用户设置的级别进行比较,用户设置级别默认是info, 如果参数level大于用户设置级别,函数会返回true,而用户设置级别的途径是通过命令etprop log.tag.xxx ?V/D/I/W/E/A ?来完成。
2. 只有 level >= 用户设置的级别才能输出,即level >= 用户设置的级别时isLoggable返回true,反之则返回false;
3. 可以通过setprop log.tag.<YOUR_LOG_TAG> <LEVEL>来设置用户日志比对级别,如adb shell setprop log.tag.XXX?D。也可以将这些属性按照log.tag.XXX=D的形式,写入/data/local.prop中, 而XXX就是代码中的字符串TAG
4. tag的长度如果超过23个字符则会抛出IllegalArgumentException异常
framework日志控制例子:
frameworks/base/services/core/java/com/android/server/ConnectivityService.java
private static final boolean DBG = true;
private static final boolean DDBG = Log.isLoggable(TAG, Log.DEBUG);
private static final boolean VDBG = Log.isLoggable(TAG, Log.VERBOSE);
if (VDBG || DDBG) log("Setting MTU size: " + iface + ", " + mtu);
?private static void log(String?s) {
?? ???????Slog.d(TAG, s);? ??
?}
C/C++接口:__android_log_is_loggable()
?int __android_log_is_loggable(int prio, const char* tag, int default_prio)
参数1: 当前代码输出的级别,会和属性log. tag.<tagname>进行比对。
参数2: 标签
参数3: 默认的比对日志级别,类似log. tag.<tagname>
参考代码:
#define LOG_EMERG ????(ANDROID_LOG_FATAL)
#define LOG_ALERT ????(ANDROID_LOG_FATAL)
#define LOG_CRIT ?????(ANDROID_LOG_FATAL)
#define LOG_ERR ??????(ANDROID_LOG_ERROR)
#define LOG_WARNING ??(ANDROID_LOG_WARN)
#define LOG_INFO ?????(ANDROID_LOG_INFO)
#define LOG_DEBUG ????(ANDROID_LOG_DEBUG)
#define LOG_VERBOSE ???(ANDROID_LOG_VERBOSE)
#define syslog(level, fmt, ...) ?\
do { \
????if(__android_log_is_loggable(level, LOG_TAG, ANDROID_LOG_INFO)){ \
????????ALOGI(fmt, ##__VA_ARGS__); \
????} \
}while(0);
总结
两种方法都可以控制日志输出, 第一种相对来说轻量一些, 第二种判断逻辑代码比第一种多写, 但是更智能些。
|