日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Android后台耗电分析及优化

發(fā)布時間:2023/12/2 综合教程 89 生活家
生活随笔 收集整理的這篇文章主要介紹了 Android后台耗电分析及优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

原文見: 在路上的blog

Android后臺耗電分析及優(yōu)化

  • 一、什么是耗電優(yōu)化?
  • 二、耗電優(yōu)化第一個方向:優(yōu)化后臺耗電
    • 1、喚醒鎖定操作卡住(前臺&后臺)
    • 2、喚醒次數(shù)過多
    • 3、WLAN掃描次數(shù)過多(后臺)
    • 4、后臺移動網(wǎng)絡(luò)使用量過高
  • 三、耗電優(yōu)化第二個方向:讓系統(tǒng)認(rèn)為是正常耗電
    • (1)海外應(yīng)用
    • (2)國內(nèi)應(yīng)用之華為后臺資源紅線標(biāo)準(zhǔn)
    • (3)經(jīng)驗性總結(jié)規(guī)則
  • 四、耗電監(jiān)控
    • 1、google vitals不適合
    • 2、合適的耗電監(jiān)控方式
      • (1)解析bugreport
      • (2)Java Hook
      • (3)插樁
  • 五、名次解釋

主要參考資料:

  • Android程序性能優(yōu)化之耗電優(yōu)化
  • Android vitals管理中心文檔

開源后臺耗電分析工具: battery_alalyze

一、什么是耗電優(yōu)化?

在實踐中,如果我們的應(yīng)用需要播放視頻、獲取GPS信息、需要拍照,這些耗電看起來是無法避免的。
如果發(fā)現(xiàn)某個應(yīng)用沒怎么使用(前臺時間很少),但是耗電卻非常多。這種情況會跟用戶的預(yù)期差別很大,這種情況就需要優(yōu)化。

二、耗電優(yōu)化第一個方向:優(yōu)化后臺耗電

根據(jù)Android Vitals定義,影響后臺耗電的動作如下:

  • 喚醒鎖定操作卡住
  • 喚醒鎖定操作卡住(后臺)
  • 喚醒次數(shù)過多
  • WLAN 掃描次數(shù)過多(后臺)
  • 網(wǎng)絡(luò)使用量過高(后臺)

1、喚醒鎖定操作卡住(前臺&后臺)

應(yīng)用會通過調(diào)用帶有 PARTIAL_WAKE_LOCK 標(biāo)記的 acquire() 來獲取部分喚醒鎖定。當(dāng)您的應(yīng)用在后臺運行時,如果部分喚醒鎖定保持了較長時間,則會變?yōu)榭ㄗ顟B(tài)(用戶看不到應(yīng)用的任何部分)。 它會阻止設(shè)備進(jìn)入低功耗狀態(tài)。部分喚醒鎖定僅應(yīng)在必要時使用,并且在不再需要時立即釋放。

Android Vitals 報告部分喚醒鎖定卡住的條件是在以下任一時段內(nèi)至少發(fā)生了一次時長達(dá) 1 小時的部分喚醒鎖定:
(1)所有情況下至少 0.70% 的電池工作時段

(2)僅在后臺運行時至少 0.10% 的電池工作時段

喚醒鎖定操作卡住的問題發(fā)現(xiàn)和修復(fù)建議

2、喚醒次數(shù)過多

喚醒是 AlarmManagerAPI 中的一種機制,可讓開發(fā)者設(shè)置鬧鐘以在指定時間喚醒設(shè)備。為設(shè)置喚醒鬧鐘,您的應(yīng)用會調(diào)用 AlarmManager 中某個帶有 RTC_WAKEUP 或 ELAPSED_REALTIME_WAKEUP 標(biāo)記的 set() 方法。當(dāng)喚醒鬧鐘觸發(fā)時,設(shè)備會在執(zhí)行鬧鐘的 onReceive() 或 onAlarm() 方法期間退出低功耗模式并保持部分喚醒鎖定。如果喚醒鬧鐘觸發(fā)次數(shù)過多,則可能會耗盡設(shè)備的電池電量。

喚醒次數(shù)過多標(biāo)準(zhǔn):用戶遇到每小時 10 次以上喚醒的電池工作時段數(shù)百分比。

  • Vital 詳細(xì)信息:
    • 受影響的工作時段數(shù):用戶遇到每小時 10 次以上喚醒的電池工作時段數(shù)百分比。電池會話是指設(shè)備在兩次充滿電之間的間隔時間。Google 僅會在設(shè)備未充電時收集這項數(shù)據(jù)。
    • 會話數(shù):系統(tǒng)已記錄的會話的大概數(shù)量。
    • 第 90/99 個百分位:10%/1% 的每日工作時段中用戶每小時遇到喚醒次數(shù)高于顯示的值。
      最低 25%:如果您的應(yīng)用發(fā)生問題的工作時段比例等于或高于顯示的閾值,則系統(tǒng)會將此應(yīng)用歸在這項指標(biāo)的最低 25% 區(qū)間(依據(jù)為 Google Play 上前 1000 個熱門應(yīng)用,按安裝量統(tǒng)計)。

喚醒過多修復(fù)及建議

3、WLAN掃描次數(shù)過多(后臺)

當(dāng)應(yīng)用在后臺執(zhí)行 WLAN 掃描時,它會喚醒 CPU,從而加快耗電速度。掃描次數(shù)過多時,設(shè)備的電池續(xù)航時間可能會明顯縮短。如果某個應(yīng)用處于 PROCESS_STATE_BACKGROUND 或 PROCESS_STATE_CACHED 狀態(tài),則會被視為在后臺運行。

WLAN 掃描次數(shù)過多的標(biāo)準(zhǔn):在后臺運行時,應(yīng)用在 0.10% 的電池工作時段內(nèi)每小時執(zhí)行的掃描超過 4 次。

建議:如果可能,您的應(yīng)用執(zhí)行 WLAN 掃描時應(yīng)該是在前臺運行。前臺服務(wù)會自動顯示通知;在前臺執(zhí)行 WLAN 掃描,從而讓用戶知道設(shè)備上發(fā)生 WLAN 掃描的原因和時間。

掃描次數(shù)過多優(yōu)化:如果您的應(yīng)用無法避免在后臺運行期間執(zhí)行 WLAN 掃描,則可能適合采用偷懶至上策略。“偷懶至上”包含三種可用于消減 WLAN 掃描次數(shù)的方法:“減少”、“推遲”和“合并”。如需了解這些方法,請參閱針對電池續(xù)航時間進(jìn)行優(yōu)化。

4、后臺移動網(wǎng)絡(luò)使用量過高

當(dāng)應(yīng)用在后臺連接移動網(wǎng)絡(luò)時,應(yīng)用會喚醒 CPU 并開啟無線裝置。如果反復(fù)執(zhí)行此操作,可能會耗盡設(shè)備的電池電量。如果某個應(yīng)用處于 PROCESS_STATE_BACKGROUND 或 PROCESS_STATE_CACHED 狀態(tài),則會被視為在后臺運行。

后臺網(wǎng)絡(luò)使用量過高的標(biāo)準(zhǔn):在后臺運行時,應(yīng)用在 0.10% 的電池工作時段內(nèi)每小時發(fā)送和接收的數(shù)據(jù)合計達(dá) 50 MB。

建議:可以將應(yīng)用的移動網(wǎng)絡(luò)使用量移至前臺,提醒用戶目前正在進(jìn)行下載,并為他們提供暫停或停止下載的控件。為此,請調(diào)用 DownloadManager 并根據(jù)情況設(shè)置 setNotificationVisibility(int)。

三、耗電優(yōu)化第二個方向:讓系統(tǒng)認(rèn)為是正常耗電

如何讓系統(tǒng)認(rèn)為是正常耗電呢?當(dāng)耗電指標(biāo)低于規(guī)則時,系統(tǒng)也就認(rèn)為是正常耗電了。

(1)海外應(yīng)用

海外應(yīng)用主要參考Google Vitals的規(guī)則。
對于Google Vitals的后臺耗電過多統(tǒng)計規(guī)則中的電池工作時段百分比,對于質(zhì)量評估來看,較難把握。所以主要關(guān)注規(guī)則的具體指標(biāo),即相對更嚴(yán)格的質(zhì)量要求:

(2)國內(nèi)應(yīng)用之華為后臺資源紅線標(biāo)準(zhǔn)

(3)經(jīng)驗性總結(jié)規(guī)則

對于國內(nèi)應(yīng)用來說,目前還沒有非常通用且權(quán)威的后臺耗電規(guī)則,根據(jù)經(jīng)驗,我們將監(jiān)控的內(nèi)容抽象成規(guī)則。
當(dāng)然不同應(yīng)用監(jiān)控的事項或者參數(shù)都不太一樣。由于每個應(yīng)用的具體情況都不太一樣。
下面是一些可以用來參考的簡單規(guī)則。

四、耗電監(jiān)控

那我們的耗電監(jiān)控系統(tǒng)應(yīng)該監(jiān)控哪些內(nèi)容,怎么樣才能比 Android Vitals 做得更好呢?

  • 監(jiān)控信息:簡單來說系統(tǒng)關(guān)心什么,我們就監(jiān)控什么,而且應(yīng)該以后臺耗電監(jiān)控為主。類似 Alarm wakeup、WakeLock、WiFi scans、Network 都是必須的,其他的可以根據(jù)應(yīng)用的實際情況。如果是地圖應(yīng)用,后臺獲取 GPS 是被允許的;如果是計步器應(yīng)用,后臺獲取 Sensor 也沒有太大問題。
  • 現(xiàn)場信息:監(jiān)控系統(tǒng)希望可以獲得完整的堆棧信息,比如哪一行代碼發(fā)起了 WiFi scans、哪一行代碼申請了 WakeLock 等。還有當(dāng)時手機是否在充電、手機的電量水平、應(yīng)用前臺和后臺時間、CPU 狀態(tài)等一些信息也可以幫助我們排查某些問題。

1、google vitals不適合

缺點:

  • 耗電規(guī)則無法修改
  • 無法拿到堆棧和其他電池信息
  • 國內(nèi)應(yīng)用無法使用

2、合適的耗電監(jiān)控方式

(1)解析bugreport

通常大家可能會使用Battery Historian來分析后臺耗電,但是不夠靈活。比如需要人工查看各資源使用情況及是否達(dá)標(biāo)。所以用python實現(xiàn)了一個簡單的分析bugreport文件的小工具;
核心代碼是剛做測開半年左右寫的,比較亂且水平有限,大家輕拍,也歡迎大家參與優(yōu)化。

  • 實現(xiàn)邏輯:
    • 重置電池統(tǒng)計信息和歷史記錄(dumpsys batterystats --reset)
    • 打開詳細(xì)的wakelock數(shù)據(jù)開關(guān),日志量較大,一般可正常保存3個小時以內(nèi)。
      • dumpsys batterystats --enable full-wake-history --啟用
      • dumpsys batterystats --disable full-wake-history --關(guān)閉
    • 導(dǎo)出bugreport文件
      • Android 7.0 and higher: adb bugreport > bugreport.zip
      • Android 6.0 and lower: adb bugreport > bugreport.txt
    • 利用battery_analyze生成后臺耗電報告

(2)Java Hook

Hook 方案的好處在于使用者接入非常簡單,不需要去修改自己的代碼。下面我以幾個比較常用的規(guī)則為例,看看如果使用 Java Hook 達(dá)到監(jiān)控的目的。

  • WakeLock:WakeLock 用來阻止 CPU、屏幕甚至是鍵盤的休眠。類似 Alarm、JobService 也會申請 WakeLock 來完成后臺 CPU 操作。WakeLock 的核心控制代碼都在PowerManagerService中,實現(xiàn)的方法非常簡單。

// 代理 PowerManagerService
ProxyHook().proxyHook(context.getSystemService(Context.POWER_SERVICE), "mService", this);@Override
public void beforeInvoke(Method method, Object[] args) {// 申請 Wakelockif (method.getName().equals("acquireWakeLock")) {if (isAppBackground()) {// 應(yīng)用后臺邏輯,獲取應(yīng)用堆棧等等     } else {// 應(yīng)用前臺邏輯,獲取應(yīng)用堆棧等等}// 釋放 Wakelock} else if (method.getName().equals("releaseWakeLock")) {// 釋放的邏輯    }
}
  • Alarm:Alarm 用來做一些定時的重復(fù)任務(wù),它一共有四個類型,其中ELAPSED_REALTIME_WAKEUP和RTC_WAKEUP類型都會喚醒設(shè)備。同樣,Alarm 的核心控制邏輯都在AlarmManagerService中,實現(xiàn)如下:
// 代理 AlarmManagerService
new ProxyHook().proxyHook(context.getSystemService
(Context.ALARM_SERVICE), "mService", this);public void beforeInvoke(Method method, Object[] args) {// 設(shè)置 Alarmif (method.getName().equals("set")) {// 不同版本參數(shù)類型的適配,獲取應(yīng)用堆棧等等// 清除 Alarm} else if (method.getName().equals("remove")) {// 清除的邏輯}
}
  • 其他:對于后臺 CPU,我們可以使用卡頓監(jiān)控相關(guān)的方法。對于后臺網(wǎng)絡(luò),同樣我們可以通過網(wǎng)絡(luò)監(jiān)控相關(guān)的方法。對于 GPS 監(jiān)控,我們可以通過 Hook 代理LOCATION_SERVICE。對于 Sensor,我們通過 Hook SENSOR_SERVICE中的“mSensorListeners”,可以拿到部分信息。

通過 Hook,我們可以在申請資源的時候?qū)⒍褩P畔⒈4嫫饋怼.?dāng)我們觸發(fā)某個規(guī)則上報問題的時候,可以將收集到的堆棧信息、電池是否充電、CPU 信息、應(yīng)用前后臺時間等輔助信息也一起帶上。

(3)插樁

雖然使用 Hook 非常簡單,但是某些規(guī)則可能不太容易找到合適的 Hook 點。而且在 Android P 之后,很多的 Hook 點都不支持了。
出于兼容性考慮,我首先想到的是寫一個基礎(chǔ)類,然后在統(tǒng)一的調(diào)用接口中增加監(jiān)控邏輯。以 WakeLock 為例:

public class WakelockMetrics {// Wakelock 申請public void acquire(PowerManager.WakeLock wakelock) {wakeLock.acquire();// 在這里增加 Wakelock 申請監(jiān)控邏輯}// Wakelock 釋放public void release(PowerManager.WakeLock wakelock, int flags) {wakelock.release();// 在這里增加 Wakelock 釋放監(jiān)控邏輯}
}

Facebook 也有一個耗電監(jiān)控的開源庫Battery-Metrics,它監(jiān)控的數(shù)據(jù)非常全,包括 Alarm、WakeLock、Camera、CPU、Network 等,而且也有收集電量充電狀態(tài)、電量水平等信息。
Battery-Metrics 只是提供了一系列的基礎(chǔ)類,在實際使用中,接入者可能需要修改大量的源碼。但對于一些第三方 SDK 或者后續(xù)增加的代碼,我們可能就不太能保證可以監(jiān)控到了。這些場景也就無法監(jiān)控了,所以 Facebook 內(nèi)部是使用插樁來動態(tài)替換。
遺憾的是,Facebook 并沒有開源它們內(nèi)部的插樁具體實現(xiàn)方案。大家可以自行搜索不同插樁方案的實現(xiàn)。
插樁方案使用起來兼容性非常好,并且使用者也沒有太大的接入成本。但是它并不是完美無缺的,對于系統(tǒng)的代碼插樁方案是無法替換的,例如 JobService 申請 PARTIAL_WAKE_LOCK 的場景。

五、名次解釋

  • 電池工作時段:是指兩次電池充滿電的時間間隔。

總結(jié)

以上是生活随笔為你收集整理的Android后台耗电分析及优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。