[譯] 如何用 Android vitals 解決應用程式的質量問題

Shawnlee發表於2018-06-26

兩篇中的第一篇:修復 ANR 事件和過度喚醒是如何提高應用在 Play Store 上的表現的

[譯] 如何用 Android vitals 解決應用程式的質量問題

對於一個應用開發者來說,沒有比開心的使用者更好的衡量成功的標準,而且最好是有很多這樣的使用者。實現這一目標的最佳方式是擁有一個人人都想用的優秀應用,不過我們所說的“優秀”指的是什麼呢?它可以歸結為兩件事:功能和應用質量。前者最終取決於你的創造力和選擇的商業模式,而後者可以客觀地衡量和改進。

在去年進行的一項 Google 內部研究中,我們檢視了 Play Store 中的一星評論,發現超過 40% 的人提到應用穩定性的問題。相對的,人們會用更高的評分和更好的評論持續獎勵那些表現最佳的應用。這使得它們在 Google Play 上獲得更好的排名,而好的排名有助於提高安裝量。不僅如此,使用者還會更加投入,並願意在這些應用程式上花費更多的時間和金錢。

因此,解決應用程式的穩定性問題可以在很大程度上決定它有多成功。

為了提供一個客觀的質量衡量標準,使你可以輕鬆發現應用需要解決哪些穩定性問題,我們在 Play Console 中新增了一個名為 Android vitals 的新模組。這個模組可以告訴你應用程式的效能和穩定性問題,而不需要在程式碼中新增儀器或庫。當你的應用程式執行在眾多裝置上的時候,Android vitals 會收集關於應用程式效能的匿名指標。即使在使用硬體實驗室進行測試時,它也會以其他方式難以獲得的規模為你提供資訊。

Android vitals 可以提醒你的問題包括崩潰、應用程式無響應(ANR)和渲染時間。這些問題都直接影響你的使用者對應用的體驗和看法。此外,還有一類使用者可能不會直接與你的應用關聯的不良應用行為:比如耗電的速度比預期的要快。

在本文中,我將著眼於以下兩個問題:

  • 過度喚醒。這會影響電池的續航時間,如果使用者無法及時充電,可能會導致他們無法使用裝置。這種行為很可能會讓使用者迅速解除安裝你的應用。
  • 應用程式無響應(ANR)事件。這些事件發生在你的應用程式 UI 凍結的時候。發生凍結時,如果你的應用位於前臺,會彈出對話方塊讓使用者選擇關閉應用或等待響應。從使用者的角度來看,這種行為與應用崩潰一樣糟糕。使用者可能不會立即解除安裝你的應用,但如果 ANR 持續存在,使用者很可能會尋找替代的應用。

過度喚醒

[譯] 如何用 Android vitals 解決應用程式的質量問題

那麼,喚醒是什麼以及它們何時變得過度呢?

為了延長電池的續航時間,螢幕關閉後,Android 裝置將通過禁用主 CPU 核心進入深度睡眠模式。除非使用者喚醒裝置,否則裝置會盡可能長時間地保持在此狀態。但是,有一些重要事件需要喚醒 CPU 並提醒使用者,例如,當鬧鐘響起或有新的聊天訊息到達時。這些警報可以通過喚醒警報(wakeup alarm)來處理,但正如我將要解釋的那樣,這並不是必須的。到目前為止,喚醒似乎是一件好事,它可以顯示重要的事件引起使用者的注意,但是如果有太多這種事件那麼電池壽命就會受到影響。

Android vitals 如何顯示過度喚醒?

瞭解你的應用是否在驅動過多的喚醒是 Android vitals 的重要任務。收集的有關你應用行為的匿名資料用於顯示自裝置完全充電後,每小時經歷超過 10 次喚醒的使用者的百分比。要檢視的關鍵點是一個紅色的圖示;這個圖示告訴你,你的應用已超出不良行為閾值。而這個閾值表示你的應用屬於 Google Play 上表現較差的應用,你應該考慮改善其行為。

[譯] 如何用 Android vitals 解決應用程式的質量問題

喚醒警報是否有其他替代方法?

在指定時間或間隔後喚醒裝置的主要方法是使用 AlarmManager API 的 RTC_WAKEUP 或 ELAPSED_REALTIME_WAKEUP 標誌來安排警報。但是一定要注意謹慎地使用此功能,而且只有在其他排程和通知機制不能更好地提供服務的情況下。當你想要使用喚醒警報時,請注意考慮以下幾點:

  • 如果你需要根據網路返回的資料來顯示資訊,可以考慮使用訊息推送來實現,例如 Firebase Cloud Messaging。使用這種機制而不是定期拉取新資料,你的應用只有在需要時才會被喚醒。

  • 如果你無法使用訊息推送並且依賴定期拉取,可以考慮使用 JobScheduler 或者是 Firebase JobDispatcher(甚至是 SyncManager 來獲取帳戶資料)。這些是比 AlarmManager 更高階別的 API,而且為更智慧的定期任務提供以下好處:

    A) 批處理 —— 許多工將被批量處理以使裝置睡眠時間更長,而不是多次喚醒系統來執行這些任務。

    B) 條件 —— 你可以指定必須滿足某些條件才能執行你的任務,例如網路可用性或電池的充電狀態。使用這些條件可以避免不必要的裝置喚醒和應用執行。

    C) 持續性和自動重試 —— 任務可以持續執行(即使重新啟動也可以),並且可以在發生故障時自動重試。

    D) Doze 相容性 —— 任務只有在不受 Doze 模式限制或應用程式待機時才會執行。

只有當訊息推送和定期任務不適合你的工作時,你才應該使用 AlarmManager 安排喚醒警報。或者從另一個角度來看,只有當你需要在特定時間啟動鬧鐘時才需要使用喚醒警報,無論網路或其他條件如何。

Android vitals 顯示過度喚醒時你應該怎麼做?

要解決過度喚醒的問題,請先確定你的應用在哪些地方設定了喚醒警報,然後降低觸發這些警報的頻率。

要確定你的應用在哪些地方設定了喚醒警報,請在 Android Studio 中開啟 AlarmManager 類,右鍵單擊 RTC_WAKEUP 或 ELAPSED_REALTIME_WAKEUP 欄位並選擇 “Find Usages”。這將顯示你專案中用到這些標誌的所有例項。審查每一個例項,看看你是否可以切換到更智慧的定時任務機制中的一種。

[譯] 如何用 Android vitals 解決應用程式的質量問題

你還可以在 Find Usages 選項中將範圍設定為“專案和庫”,以確定你的依賴庫是否使用了 AlarmManager API。如果是,你應該考慮使用替代庫或向作者報告這個問題。

如果你決定必須使用喚醒警報,那麼如果你提供了符合以下要求的警報標籤,則 Play Console 可以提供更好的分析資料:

  • 在你的警報標籤名稱中包含你的包名、類名或方法名。這也可以幫助你輕鬆識別警報設定在你原始碼中的什麼位置。
  • 請勿使用 Class#getName() 作為警報名稱,因為它可能會被 Proguard 混淆。改用硬編碼的字串。
  • 不要將計數器或其他唯一識別符號新增到警報標籤,因為系統可能會丟棄標籤,而且無法將它們聚合成有用的資料。

應用程式無響應

[譯] 如何用 Android vitals 解決應用程式的質量問題

那麼,什麼是應用程式無響應(ANR),它又是如何影響使用者的呢?

對於使用者來說,ANR 是當他們嘗試與你的應用進行互動時,該介面被凍結。介面保持凍結幾秒鐘後,會顯示一個對話方塊,讓使用者選擇等待或強制應用程式退出。

從應用程式開發的角度來看,當應用程式因為執行耗時操作(如磁碟或網路讀寫)阻塞主執行緒時,就會發生 ANR。主執行緒(有時稱為 UI 執行緒)負責響應使用者事件並重新整理螢幕上每秒繪製六十次的內容。因此,將任何可能延遲其工作的操作都轉移到後臺執行緒是至關重要的。

Android vitals 如何顯示 ANR?

使用收集到的有關你應用 ANR 事件的匿名資料,Android vitals 提供了有關 ANR 的多個級別的詳細資訊。主螢幕顯示你應用程式中發生 ANR 的 Activity 的概況。這顯示了使用者經歷過至少一次 ANR 的每日會話的百分比,以及之前最近 30 天的單獨報告。還提供了不良行為的閾值。

[譯] 如何用 Android vitals 解決應用程式的質量問題

詳細資訊檢視的 ANR 比例頁面顯示了 ANR 比例隨時間變化的詳細資訊,以及按應用版本、Activity 名稱、ANR 型別和 Android 版本顯示的 ANR 資訊。你可以通過 APK 版本號、支援的裝置、作業系統版本和時間段來過濾這些資料。

[譯] 如何用 Android vitals 解決應用程式的質量問題

你還可以從 ANRs & crashes 部分獲取更多詳細資訊。

[譯] 如何用 Android vitals 解決應用程式的質量問題

ANR 的常見原因是什麼?

如前所述,當應用程式程式阻塞主執行緒時就會發生 ANR。幾乎任何原因都可能導致這種阻塞,但最常見的原因包括:

  • 在主執行緒上執行磁碟或網路讀寫操作。這是迄今為止 ANR 最常見的原因。雖然大多數開發人員都認為你不應該在主執行緒上讀取或寫入資料到磁碟或網路,但有時我們總會無意間這麼做。在理想情況下從磁碟讀取幾個位元組可能不會導致 ANR,但是這絕不是一個好主意。如果使用者使用的裝置快閃記憶體很慢怎麼辦?如果他們的裝置受到來自其他應用程式同時讀取和寫入的巨大壓力,而你的應用程式在佇列中等待執行“快速”讀取操作時又該怎麼辦?切勿在主執行緒上執行讀寫操作。
  • 在主執行緒上執行長時間計算。那麼記憶體裡的計算會怎麼樣呢?RAM 不會受長時間訪問的影響,較小的操作應該沒問題。但是,當你開始在迴圈中執行復雜計算或處理大型資料集時,可以輕鬆阻塞主執行緒。可以考慮調整包含數百萬畫素的大影像的大小,或解析大塊的 HTML 文字,然後在 TextView 中顯示。一般來說,最好讓你的應用在後臺執行這些操作。
  • 從主執行緒向另一個程式執行同步繫結呼叫。與磁碟或網路操作類似,在跨程式邊界進行阻塞呼叫時,程式執行會傳遞到你無法控制的某個位置。如果其他程式很忙怎麼辦?如果它需要訪問磁碟或網路來響應你的請求怎麼辦?另外,資料傳遞給另一個程式需要進行序列化和反序列化,這也需要時間。最好從後臺執行緒進行程式間呼叫。
  • 使用同步。即使你將繁重的操作移動到後臺執行緒,也需要與主執行緒進行通訊以顯示進度或計算的結果。多執行緒程式設計並不容易,而且在使用同步進行鎖定時,通常很難保證不會阻塞執行。在最糟糕的情況下,它甚至可能導致死鎖,執行緒之間互相阻塞永久等待下去。最好不要自己設計同步,使用專門的解決方案會更好一些,比如 Handler,從後臺執行緒傳遞不可變的資料到主執行緒。

我如何檢測 ANR 的原因?

查詢 ANR 的原因可能會非常棘手,就拿 URL 類來說吧。 你覺得確定兩個 URL 是否相同的 URL#equals 方法是否會被阻塞?SharedPreferences 又會怎樣?如果你在後臺從中讀取值,可以在主執行緒上呼叫 getSharedPreferences 方法嗎?在這兩種情況下,答案是這些都可能是長時間阻塞操作。

幸運的是,StrictMode 使查詢 ANR 不再靠猜的。在除錯版本中使用這個工具可以捕獲主執行緒上意外的磁碟和網路訪問。在應用程式啟動時使用 StrictMode#setThreadPolicy 可以自定義你想要檢測的內容,包括磁碟和網路讀寫,甚至可以通過 StrictMode#noteSlowCall 在應用程式中觸發自定義的慢速呼叫。你還可以選擇 StrictMode 在檢測到阻塞呼叫時如何提醒你:通過讓應用程式崩潰、Log 資訊或者是顯示對話方塊。更多詳細資訊,請參閱 ThreadPolicy.Builder類

一旦你消除了主執行緒中的阻塞呼叫,記得在將你的應用程式釋出到 Play Store 之前關閉 StrictMode。

消除過度喚醒和 ANR 將提高應用程式的質量和可用性,提高評分和評論,進而實現更多安裝。通過檢視 Android vitals,你可以快速輕鬆地發現是否存在需要解決的問題。在程式碼中查詢和解決這些問題並不總是那麼直截了當,但有些工具和技術可以幫你更高效地完成這些工作。

Android vitals 還可以給你提供更多幫助,我會在下一篇文章裡介紹更多這些功能。我將在 5 月 8 日星期二下午 3 點,在 Google I/O 2018 大會上和同事 Fergus Hurley 以及 Joel Newman 一起演示 “Android vitals:除錯應用程式效能和收穫獎勵” 的環節。如果你在那裡或者想通過直播瞭解更多關於 Android vitals、最新的 Play Console 和 Android Studio 工具以及幫助你提高應用質量的意見,請加入我們。


如果你對 Android vitals 有任何想法或疑問,請通過 #AskPlayDev 傳送推特告知我們。我們會通過 @GooglePlayDev 回覆你,我們也會定期在上面分享有關如何在 Google Play 上取得成功的新聞和提示。

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章