在平常開發中,日誌是必不可少的一步,數據查看、bug 追蹤、數據收集等都須要用到日誌,Android 系統提供了 Log 類來實現,可是每次都要輸入一個 TAG, 會很是的麻煩。因此你能夠本身封裝一個 Log 框架,也可使用一些開源日誌框架,好比:Timer、XLog、Logger 等,在這裏主要介紹一下 Logger。android
Logger 是 Orhan Obut 搞的, Simple, pretty and powerful logger for android.github
String,String format,數組,集合,XML和JSON,同時也可將日誌存儲到文件,也可輸出線程方法等詳細信息json
implementation 'com.orhanobut:logger:2.2.0'
複製代碼
Logger.addLogAdapter(new AndroidLogAdapter());
複製代碼
接下來就是能夠直接使用了api
Logger.d("message");
複製代碼
默認輸出 Log 以及所在類名,方法名,行號,線程等相關信息。若是不想顯示除 Log 外的其餘信息,能夠對 Adapter 進行相關設置,數組
FormatStrategy formatStrategy = PrettyFormatStrategy.newBuilder()
.showThreadInfo(false) // 展現線程信息
.methodCount(5) // 展現調用的方法個數,默認是 2
.methodOffset(0) // 跳過堆棧中的方法個數, 默認是 0
.tag("My custom tag") // TAG 內容. 默認是 PRETTY_LOGGER
.build();
Logger.addLogAdapter(new AndroidLogAdapter(formatStrategy));
複製代碼
顯示以下,若是 methodOffset 爲1,則不展現 MainActivity.onCreate(),只顯示其餘 4 個。app
若是須要將日誌存儲到本地文件,則須要使用 DiskLogAdapter, 同時須要聲明存儲權限,Logger 默認生成 csv 文件,存儲在 /storage/emulated/0/logger 目錄下,框架
Logger.addLogAdapter(new DiskLogAdapter());
複製代碼
若是針對不一樣的頁面 Logger 的配置不一樣, 可使用 Logger.clearLogAdapters(), 而後進行從新配置。oop
message 除了是 String 類型,還能夠是集合,數組,源碼分析
Logger.t("tag").e("Custom tag for only one use");
Logger.json("{ \"key\": 3, \"value\": something}");
Logger.d(Arrays.asList("foo", "bar"));
Logger.d(new int[]{2,3,19,4});
Logger.d("");
Map<String, String> map = new HashMap<>();
map.put("key", "value");
map.put("key1", "value2");
Logger.d(map);
Logger.d("message %s", " erro");
複製代碼
Logger 最終調用的仍是 Log.println(int priority, String tag, String msg) 方法,以 Logger.d() 爲例, 一步步查看
Logger.d("message");
指向 LoggerPrinter.d() 方法, 指向 log(), 因爲能夠同時添加多個 adapter, 因此在這裏要進行一次 for 循環,遍歷全部的 adapter
以 AndroidLogAdapter 爲例,指向 AndroidLogAdapter 的 log() 方法, 最終使用系統 Log.println() 輸出日誌。
上傳客戶端日誌,對於分析 app 運行狀況可用戶使用習慣是相當重要的一步,可是 Logger 的存儲路徑試固定的,沒有提供相關的 api 進行設置,因此能夠經過分析其中的原理,而後自定義一個 adapter. 對於這裏的路徑我建議存儲在 /Android/data/包名, 由於此路徑不須要獲取用戶權限,能夠直接使用。
經過 new DiskLogAdapter(), 在其構造方法中 CsvFormatStrategy 使用 Builder 模式 建立了一個 CsvFormatStrategy 實例, 在 builder() 能夠看到具體的路徑,由於一旦在子線程中操做,Handler 須要手動啓動 Looper, 因此這裏 經過 HandlerThread 獲取 Looper 傳遞給 Handler, 經過 DiskLogStrategy.WriteHandler 建立 Handler, 將將文件路徑傳遞給 DiskLogStrategy.WriteHandler, 同時經過構造方法生成 DiskLogStrategy 對象,將 handler 傳遞給 DiskLogStrategy, 當輸出 Log 時調用 DiskLogStrategy 的 log() 方法,經過 log() 方法中 handler 將 message 發送出去, 而後交給 handler 處理,存儲到 DiskLogStrategy.WriteHandler 中的路徑。
第一次來來掘金髮博客,歡迎指正
end