Logger 日誌管理
1.Logger 是什麼
在我們日常的開發中,肯定是少不了要和 Log 打交道,回想一下我們是怎麼使用 Log 的:先定義一個靜態常量 TAG,TAG 的值通常是當前類的類名,然後在需要列印 Log 的地方,呼叫 Log.d(TAG, "要列印的內容")
。每次新寫一個類,都要寫一個
TAG,這也就算了,最苦逼的是,專案一上線,還要手動去把每個 Log 註釋掉。。。
當然,有的同學可能要說,這又沒什麼,自己封裝一個 Log 不就行了。但是對新手來說,自己封裝有一定的難度,如果有現成的開源庫可以直接拿來用就好了。
Github 上的大牛當然也注意到了這個情況,於是開源日誌庫 Logger 誕生了。
Logger 提供以下功能:
- 執行緒的資訊
- 類的資訊
- 方法的資訊
- 將 JSON 文字人性化輸出
- 將換行符人性化輸出
- 簡潔的輸出
- 從日誌跳轉到原始碼
Logger 與 原生 Log 最大的不同就是:Logger 打印出來的日誌一目瞭然,引用下官方 Github 上的圖片,看下原生 Log 和 Logger 列印日誌的區別:
原生 Log 列印的日誌:
Logger 列印的日誌:
可以看到,Logger 列印的日誌把多餘的日誌全部忽略了,只顯示對我們有用的日誌,而且還把日誌框了起來,可以讓我們看得更舒服。不得不說,Logger 做的實在是太人性化了。
Logger 使用方法也不難,Logger 開源庫的
2.Logger 的使用
開啟 Android Studio,新建 LoggerTest 專案。
1.匯入依賴
在 LoggerTest / app/ build.gradle 中的 dependencies 中,匯入依賴,程式碼如下:
dependencies {
compile 'com.orhanobut:logger:1.15'
}
然後 Android Studio 應該會彈出 Sync Now
,也就是箭頭 1 指向的位置,如圖:
如果彈出了 Sync Now
,就點選它,如果沒有彈出,就點選箭頭 2 指向的選項。
等 Grade 構建完,我們就可以使用 Logger了。
2.簡單使用
Logger 的使用方法和原生 Log 差不多,我們先來嘗試下列印一個簡單文字。
修改 MainActivity.java 中的 onCreate() 方法,程式碼如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.d("執行了 onCreate");
}
咦,怎麼沒寫 TAG?其實,Logger 是有它自己預設的 TAG 的,預設的 TAG 是 PRETTYLOGGER
,我們執行一下程式,看一下輸出日誌:
我們可以看到,已經成功的將日誌輸出了,而且比我們之前用的原生 Log 輸出的美觀多了,日誌資訊一目瞭然。箭頭指向的就是 Logger 預設的 TAG,所以如果你想讓 Logcat 只顯示你自己列印的日誌,可以在日誌過濾器中,將預設 TAG 新增進去。
或者直接在過濾框中新增:
3.列印更多型別資料
Logger 還支援列印 JSON,XML 等格式的資料。
1.JSON 型別資料
private String JSON_CONTENT = "{\"weatherinfo\":{\"city\":\"北京\",\"cityid\":\"101010100\"," +
"\"temp\":\"18\",\"WD\":\"東南風\",\"WS\":\"1級\",\"SD\":\"17%\",\"WSE\":\"1\"," +
"\"time\":\"17:05\",\"isRadar\":\"1\",\"Radar\":\"JC_RADAR_AZ9010_JB\"," +
"\"njd\":\"暫無實況\",\"qy\":\"1011\",\"rain\":\"0\"}}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.json(JSON_CONTENT);
}
2.XML 型別資料
private String XML_CONTENT = "<china dn=\"nay\"><city quName=\"黑龍江\" pyName=\"heilongjiang\" " +
"cityname=\"哈爾濱\" state1=\"1\" state2=\"1\" stateDetailed=\"多雲\"/><city quName=\"吉林\"" +
" pyName=\"jilin\" " +
"cityname=\"長春\" state1=\"0\" state2=\"0\" stateDetailed=\"晴\"/><city quName=\"遼寧\" " +
"pyName=\"liaoning\" " +
"cityname=\"瀋陽\" state1=\"1\" state2=\"0\" stateDetailed=\"多雲轉晴\"/><city " +
"quName=\"海南\" pyName=\"hainan\" " +
"cityname=\"海口\" state1=\"22\" state2=\"21\" stateDetailed=\"中到大雨轉小到中雨\"/></china>";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.xml(XML_CONTENT);
}
3.List 型別資料
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// List 型別資料
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
Logger.d(list);
}
4.Map 型別資料
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Map 型別資料
Map<String, String> map = new HashMap<>();
map.put("key_hello", "hello");
map.put("key_world", "world");
Logger.d(map);
}
5.Set 型別資料
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set 型別資料
Set<String> set = new HashSet<>();
set.add(new String("hello"));
set.add(new String("world"));
Logger.d(set);
}
4.字串格式化
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.d("hello %s %d", "world", 5);
}
5.自定義 TAG
如果你不滿意預設的 TAG,也可以自己定義一個 TAG,只需要呼叫一次 Logger.init() 就行了。因為只需要呼叫一次,所以可以在 Application 中來完成 Logger 的初始化。
新建 MyApplication 繼承 Application,程式碼如下:
public class MyApplication extends Application {
private static String TAG = "LoggerTest";
@Override
public void onCreate() {
super.onCreate();
Logger.init(TAG);
}
}
修改 AndroidManifest.xml 中 application 的屬性,新增 android:name=".MyApplication"
,AndroidManifest.xml 程式碼如下:
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
這樣 App 啟動時,初始化的就是我們自定義的 MyApplication 了。然後我們在 MainActivity 的 onCreate() 中列印一下日誌,看下自定義的 TAG 生效了沒。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.d("hello world");
}
可以看到,我們自定義的 TAG 已經生效了。那麼有的同學可能會有疑問了,我要是不想一直用這個 TAG 呢,要是臨時想換個 TAG 用呢,當然也是有辦法的,呼叫 Logger.t("臨時TAG名").d()
,就能使用臨時的 TAG 列印日誌了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Logger.t("MyTag").d("hello world");
}
可以看到,臨時的 TAG 名被追加到自定義 TAG 的後面了。
6.設定不列印日誌
之前說了,日誌只是開發的時候需要用到,等到專案上線就不能用了。Logger 當然也考慮到了這一點,通過設定Logger.init(TAG).logLevel(LogLevel.NONE)
可以設定為不列印日誌。logLevel() 方法預設的引數是 LogLevel.FULL
,也就是列印全部日誌。修改
MyApplication 的 onCreate() 方法:
@Override
public void onCreate() {
super.onCreate();
Logger.init(TAG).logLevel(LogLevel.NONE);
}
執行一下,可以發現 Logger 沒有列印日誌。
7.列印 Exception
Logger 列印 Exception,可以很清晰的看到 Exception 資訊,這裡我們寫一個數組越界異常:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int[] a = new int[3];
try {
a[4] = 3;
} catch (Exception e) {
Logger.e(e, "message");
}
}
8.更多個性化設定
Logger 還有一些個性化設定,比如
Logger.init(TAG)
.methodCount(3) // 方法棧列印的個數,預設是 2
.hideThreadInfo() // // 隱藏執行緒資訊,預設顯示
.methodOffset(2) // 設定呼叫堆疊的函式偏移值,預設是 0
.logAdapter(new AndroidLogAdapter()); // 自定義一個列印介面卡
有興趣的同學可以去 Logger 的 Github 主頁 檢視Logger 的更多用法。