天天看點

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

Android App-BlockCanary

目錄

1. BlockCanary介紹 2

1.1 功能 3

2. 為什麼要使用BlockCanary? 4

3.1配置 build.gradle檔案 5

3.2 建立一個類,繼承自BlockCanaryContext,實作自己的監控上下文,代碼示意如下 5

3.3 初始化Block的配置資訊 6

3.4 檢測卡頓 6

4.原理 9

5. 總結 12

  1. BlockCanary介紹

BlockCanary是Android平台上的一個輕量的,非侵入式的性能監控元件,應用隻需要簡單地加幾行,提供一些該元件需要的上下文環境就可以在使用應用的時候檢測主線程上的各種卡頓問題,并通過元件提供的各種資訊分析出原因并進行修複。

BlockCanary對主線程操作進行了完全透明的監控,并能輸出有效的資訊,幫助開發分析、定位到問題所在,迅速優化應用。其特點有:

  1. 非侵入式,簡單的兩行就打開監控,不需要到處打點,破壞代碼優雅性。
  2. 精準,輸出的資訊可以幫助定位到問題所在(精确到行),不需要像Logcat一樣,慢慢去找。

目前包括了核心監控輸出檔案,以及UI顯示卡頓資訊功能。僅支援Android端。

    1. 功能

BlockCanary會在發生卡頓(通過MonitorEnv的getConfigBlockThreshold設定)的時候記錄各種資訊,輸出到配置目錄下的檔案,并彈出消息欄通知(可關閉)。

簡單的使用如在開發、測試的時候,Debug包啟用

  1. 開發可以通過圖形展示界面直接看資訊,然後進行修複
  2. 測試可以把log丢給開發,也可以通過卡慢詳情頁右上角的更多按鈕,分享到各種聊天軟體
  3. 生成一堆的log,慢慢過濾記錄下重要的卡頓

還可以通過Release包使用者端定時開啟監控并上報log,比如監控,背景比對堆棧過濾同類原因,提供給開發更大的樣本環境來優化應用。

dump的資訊包括:

  1. 基本資訊:安裝包标示、機型、api等級、uid、CPU核心數、程序名、記憶體、版本号等
  2. 耗時資訊:實際耗時、主線程時鐘耗時、卡頓開始時間和結束時間
  3. CPU資訊:時間段内CPU是否忙,時間段内的系統CPU/應用CPU占比,I/O占CPU使用率
  4. 堆棧資訊:發生卡慢前的最近堆棧,可以用來幫助定位卡慢發生的地方和重制路徑
  1. 為什麼要使用BlockCanary?

App開發:在複雜的項目環境中,由于TS代碼龐大,業務複雜,包含各種第三方庫,如果偶爾再來個jni調用,不能快速定位問題,是以在出現了卡頓的時候,我們很難定位到底是哪裡出現了問題,即便知道是哪一個Activity/Fragment,也仍然需要進去裡面一行一行看,數千行的類再加上跳來跳去調來調去的,結果就是不了了之随它去了,實在不行了再優化吧。于是一拖再拖,最後可能壓根就改不動了,用戶端越來越卡。

事實上,很多情況下卡頓不是必現的,比如在我們的公司APP中,它們可能與機型、環境、操作等有關,存在偶然性,即使發生了,再去查那如山般的logcat,也不一定能找到卡頓的原因,是我們自己的應用導緻的還是其他應用搶占資源導緻的?是哪些方法導緻的?很難去回朔。有些機型自己修改了api導緻的卡頓,還必須拿那台機器才能去調試找原因。

BlockCanary就是來解決這個問題的。告别打點和調試,哪裡卡頓,一目了然。

3.  如何使用

3.1配置 build.gradle檔案

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

compile 'com.github.markzhai:blockcanary-android:1.5.0'

// 僅在debug包啟用BlockCanary進行卡頓監控和提示的話,可以這麼用

debugCompile 'com.github.markzhai:blockcanary-android:1.5.0'

releaseCompile 'com.github.markzhai:blockcanary-no-op:1.5.0'

3.2 建立一個類,繼承自BlockCanaryContext,實作自己的監控上下文,代碼示意如下

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

3.3 初始化Block的配置資訊

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

BlockCanary.install(this, new AppContext()).start();

環境搭建完畢,我們來模拟一個主界面卡頓的代碼,用BlockCanary進行檢測

3.4 檢測卡頓

  1. 在xml布局中添加一個按鈕,來觸發模拟卡頓的代碼
BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理
  1. 在代碼中使主線程阻塞
BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

整個程式界面如下:

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

當我們點選按鈕之後,檢視BlockCanary給我們的提示資訊:

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

日志輸出:

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

我們可以清晰的看到,第48行代碼就是界面的元兇,我們就可以修改48行的代碼來解決界面卡頓的狀況.

4.原理

熟悉Message/Looper/Handler系列的同學們一定知道Looper.java中這麼一段:

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

即整個應用的主線程,隻有這一個looper,不管有多少handler,最後都會回到這裡。

Looper的loop方法中有這麼一段

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

這個Printer - mLogging,它在每個message處理的前後被調用,而如果主線程卡住了,不就是在dispatchMessage裡卡住了嗎?

BlockCanar卡頓監測架構分析Android App-BlockCanary4.原理

該元件利用了主線程的消息隊列處理機制,通過

Looper.getMainLooper().setMessageLogging(mainLooperPrinter);

并在mainLooperPrinter中判斷start和end,來擷取主線程dispatch該message的開始和結束時間,并判定該時間超過門檻值(如2000毫秒)為主線程卡慢發生,并dump出各種資訊,提供開發者分析性能瓶頸。

  1. 總結

BlockCanary作為一個Android元件,目前還有局限性,因為其在一個完整的監控系統中隻是一個生産者,還需要對應的開發去分析日志,比如歸類排序,以便看出哪些卡慢更有修複價值,需要優先處理;又比如需要過濾機型,有些奇葩機型的問題造成的卡慢,到底要不要去修複是要修複。扯遠一點的話,完全還能用來做鍊條監控,比如一個完整的流程是A -> B -> D -> E, 但是某個時間節點突然A -> B -> D後沒有到達E,這時候監控就可以發出預警,讓開發人員及時定位。