举例说明android源代码调试中加入的log方法
在查看android源代码过程中, 只是看代码, 往往没有办法验证对代码的估测是否准确, 这时我们经常通过插入自己的log的方式来测试 某个函数是否调用到, 某个参数在运行过程中的值是多少. 下面jwisp把android各层中加入log语句的方法整理如下.
1. java代码
在android源码中, 只要是java代码基本上都在framework中 , 所有的java代码中, 加入logo的方式也就三步:
(a) 导入log包
import android.util.Log;
(b) 定义log标签
很多java类的第一句代码已经定义了当前类的TAG,比如DeviceStorageMonitorService.java类中的第一句
private static final String TAG = "DeviceStorageMonitorService";
当然我们也可以定义自己的标签, 以便在从上到下中, 只打印我们自己关注的log
private static final String MYTAG = "MytagTest";
(c) 添加log语句, Log的输出有 : v, i, d, w, e 五种级别
比如, 我们需要在电池管理BatteryService.java中打印出每次电量变化后的的log, 怎么实现呢
在BatteryService.java(frameworks/base/services/java/com/android/server)中找到update()方法, 在其中添加如下代码:
if (mBatteryLevel != mLastBatteryLevel){ Log.i(MYTAG, "BatteryService.java -> update : mBatteryLevel = " +mBatteryLevel); }
在设备或模拟器运行后, 只需要敲入如下命令即可在电量发生变化时, 打印出最新的电量值.
logcat -s MytagTest
2. c/c++代码
在各种jni, hal层, 驱动层都是c和c++的代码, 在这里插入log, 可以帮助我们找到上层调用下来的参数是多少, 调用的是哪个具体函数等.
网上很多人给的建议还要修改android.mk文件, 其实远不用那么麻烦.
(a) 添加tag标签, 很多tag已经添加好了, 我们可以注释掉系统的tag, 然后添加自己的tag
比如在HAL层中的距离传感器 ProximitySensor.cpp中
在代码的最上方include之前
#define LOG_TAG "ProximitySensor"
(b) 引入log库
#include <utils/Log.h>
(c) 加入log语句
在这一步中, 和java不同的是, 不能加入不同的tag标签只能用当前源文件的标签
比如jwisp想从距离传感器中输出, 每次从驱动上报来的psensor数值是多少
在readEvents函数中的while循环中加入
LOGI("ProximitySensor.cpp -> readEvent() : event->value = %d", event->value);
3. 在mk文件中加入log
很多人都不知道, mk文件在运行的时候(也就是android源码编译的时候)也可以输出log, 这大大的方便我们调试编译信息.
在make文件中有两种log级别error和warning :
$(error TEXT...) $(warning TEXT...)
用error可以准确定位我们需要的log信息, 因为编译会终止, 一般来说终止的地方会有我们的log信息,
warning不会终止在我们的log信息上, 大家可以根据自己的情况来选择.
另外,还可以在编译输出的log语句中加入mk定义的变量信息
举例, 比如我们需要知道libsensors目录下的so编译后叫什么名字, 通过在此目录下的android.mk文件中加入以下代码来输出log:
在LOGCAL_MODULE 的定义之后, 写上
$(error module is $(LOCAL_MODULE))
输出结果:
hardware/sansung/libsensors/Android.mk:27: *** module is Sensors.sansung. Stop.
Over