在查看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.