InputDispatcher的调试日志isLoggable动态开放logcat实战使用
背景:
在学习input专题课程后,那么就可以正常对所有和input相关的问题进行分析,经常分析的类就是InputDispatcher,平时如果看正常的logcat输出,发现InputDispatcher相关的日志非常少,基本上没办法进行有价值的分析。
但是针对Input相关的日志,其实android自身是带了很多的日志埋点,只是没有默认开放这些日志,具体情况以前讲解anr相关问题分析时候,有讲解过一种暴力的方法:
即直接写死为true,然后重新编译,但是这样确实可以打印调试日志,但是发布正式版本肯定关闭,而且无法在正式版本放开打印,所以这个方法还是不够动态智能,但是明显从日志注释可以看出实际上是可以进行动态开发,根本不需要修改代码重新编译。
/*** Log debug messages about the dispatch cycle.* Enable this via "adb shell setprop log.tag.InputDispatcherDispatchCycle DEBUG" (requires restart)*/
确实有告诉我们这个命令adb shell setprop log.tag.InputDispatcherDispatchCycle DEBUG命令可以放开,下面来剖析出为啥可以动态控制日志打印。
isLoggable方法
下面来看看DEBUG_DISPATCH_CYCLE的值是由谁控制的
/*** Log debug messages about the dispatch cycle.* Enable this via "adb shell setprop log.tag.InputDispatcherDispatchCycle DEBUG" (requires restart)*/
const bool DEBUG_DISPATCH_CYCLE =
__android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG "DispatchCycle", ANDROID_LOG_INFO);
可以看到__android_log_is_loggable这个方法,它来负责控制DEBUG_DISPATCH_CYCLE值。这里__android_log_is_loggable在java层面其实也有个一一对应的方法isLoggable。
frameworks/base/core/java/android/util/Log.java
/*** Checks to see whether or not a log for the specified tag is loggable at the specified level.** The default level of any tag is set to INFO. This means that any level above and including* INFO will be logged. Before you make any calls to a logging method you should check to see* if your tag should be logged. You can change the default level by setting a system property:* 'setprop log.tag.<YOUR_LOG_TAG> <LEVEL>'* Where level is either VERBOSE, DEBUG, INFO, WARN, ERROR, or ASSERT.* You can also create a local.prop file that with the following in it:* 'log.tag.<YOUR_LOG_TAG>=<LEVEL>'* and place that in /data/local.prop.** @param tag The tag to check.* @param level The level to check.* @return Whether or not that this is allowed to be logged.* @throws IllegalArgumentException is thrown if the tag.length() > 23* for Nougat (7.0) and prior releases (API <= 25), there is no* tag limit of concern after this API level.*/@FastNativepublic static native boolean isLoggable(@Nullable String tag, @Level int level);
注释其实很详细了,简单说这个方法检测指定的tag是可以在这个level进行打印,默认等级是INFO,而且是可以通过setprop来进行控制的这个tag的输出level。
java方法对应到native就是__android_log_is_loggable
综上可以看得出
__android_log_is_loggable(ANDROID_LOG_DEBUG, LOG_TAG “DispatchCycle”, ANDROID_LOG_INFO);
就是检测一下log.tag.InputDispatcherDispatchCycle这个属性设置的log输出级别,如果没有设置默认就是有INFO,那么__android_log_is_loggable就会返回false,如果log.tag.InputDispatcherDispatchCycle有设置为DEBUG,则返回true。
这样有了这个判断既可以精细的控制打印日志情况。
实战开放Input相关日志:
下面来实战开放一下InputDispatcher相关的日志,这里主要介绍2种方法:
1、直接shell命令操作setprop设置方法,这里就是使用如下命令:
adb shell setprop log.tag.InputDispatcherDispatchCycle DEBUG
但是这里注意啦,虽然设置了,但是DEBUG_DISPATCH_CYCLE是在系统启动时候就已经设置了,所以这个时候设置后肯定不会立即有效,这里需要考虑让进程进行重启,注意这里不是系统直接重启,模拟器上测试重新进行模拟器启动,发现上次设置的属性prop并没有保存,所以只能对进程进行kill,改进后命令如下:
adb shell setprop log.tag.InputDispatcherDispatchCycle DEBUG
adb shell killall system_server
2、永久保存法,这样就不需要每次重启模拟器来进行prop设置
在data/local.prop文件中加入如下属性:
上面完成后可以来检验一下日志是否可以输出:
设置属性获取添加prop后就可以看到触摸屏幕就有如下输出:
更多framework详细代码和资料参考如下链接
投屏专题部分:
https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
其他课程七件套专题:
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw
视频试看:
https://www.bilibili.com/video/BV1wc41117L4/
参考相关链接:
https://blog.csdn.net/zhimokf/article/details/137958615
更多framework假威风耗:androidframework007