解決Android 高CPU占用率的問題
背景
最近測試測試APP的一個功能,發(fā)現(xiàn)點(diǎn)擊頁面上的按鈕后,CPU占有率比之前的版本要高,達(dá)到了4%,之前的版本只有不到1%。由于兩個版本之間代碼提交特別多,無法直接通過代碼變動來對比分析。只好直接通過AS工具profiler來分析應(yīng)用CPU占用了,看下如何優(yōu)化。
分析過程
首先從測試同學(xué)口中知道了CPU占用出現(xiàn)異常的場景是點(diǎn)擊頁面上的功能A的按鈕。OK,那我們就從點(diǎn)擊這個按鈕入手。首先打開Profiler,選擇對應(yīng)的APP進(jìn)程,開始監(jiān)聽當(dāng)前進(jìn)程的CPU占用率。
雙擊CPU一行,我們進(jìn)入到CPU詳情頁面,如下:
可以看到在左側(cè),有4個選項,且下方有record按鈕。這里的含義是,我們通過點(diǎn)擊record后,profile會開始記錄接下來一段時間內(nèi),詳細(xì)的CPU占用信息,記錄哪些信息呢,通過上述四個選項供我們選擇。
- Callstack Sample
會顯示當(dāng)前這段時間內(nèi),涉及到的進(jìn)程以及調(diào)用棧都有哪些,會精細(xì)到進(jìn)程和具體代碼。
- System Trace
會顯示詳細(xì)的信息,包括VSYNC UI繪制信號,內(nèi)存占用(不是詳細(xì)內(nèi)存占用),各個線程的運(yùn)行時間和CPU占用。也會精確到代碼,但是不會特別詳細(xì)。適合分析record中等時長的數(shù)據(jù)。此外這里包含的信息會很多,有助于先手分析。
- Java/Kotlin Method Trace
內(nèi)容更詳細(xì),會精細(xì)到各行代碼,但是這個不適合record抓取太長時間的文件,因為AS分析會占用很長時間。
我們先選擇SystemTrace,點(diǎn)擊Record開始記錄信息,我們接著點(diǎn)擊功能A按鈕,開始復(fù)現(xiàn)問題場景,問題復(fù)現(xiàn),點(diǎn)擊Stop按鈕停止抓取,接著AS會自動解析文件,生成我們詳細(xì)信息,如下圖:
可以看到UI的刷新VSYNC信號刷新很頻繁,對應(yīng)下方主線程代碼,存在不少峰值。我們放大下方代碼峰值,找到最下方峰頂代碼,
可以看到下方在layout中,不停的obtainview,這里有可能是一個列表,ListView或者rectclerview,在不停的更新數(shù)據(jù)。
我們接著抓一份Java Kotlin Method Trace分析看下:
注意這里要點(diǎn)開:
然后我們隨意找到一個峰值,查看其代碼源:
這里可以直接直觀的看到定位到了我們的代碼,LogViewer控件,我們點(diǎn)進(jìn)去查看源碼,會發(fā)現(xiàn)里邊定義了一個listView。這個ListView的功能是在APP上顯示logcat日志,當(dāng)點(diǎn)擊功能A按鈕時,會產(chǎn)生大量日志,然后每次需要打印一行日志時候,就會全部更新listView的所有控件,(代碼內(nèi)容不方便粘貼)所以造成APP UI繪制高頻率進(jìn)行,導(dǎo)致CPU的占用率居高。
定位到問題了:ListView不停的刷新UI,導(dǎo)致VSYNC不停的觸發(fā)繪制,導(dǎo)致CPU占用率高
解決問題
現(xiàn)在我們定位到了問題所在,那么怎么解決呢?
第一步,極端化,直接去掉對應(yīng)UI
首先我們最直接的方法就是把這個UI直接屏蔽掉,不去初始化以及展示這個UI。
這種處理下,我們看下數(shù)據(jù),如圖,很明顯,VSYNC觸發(fā)周期長了,UI繪制頻率下來了,交給測試一看,CPU占用率降到了1.1%, 直接降了3%。
但是直接去掉這個UI,其實不是很妥,畢竟這樣相當(dāng)于這個UI需求給廢了。 我們從ListView代碼入手,ListView會產(chǎn)生很多個子View,在我們這個需求中,需要顯示logcat日志,意味著,每一行日志都會新生成一個view放入到logcat中,日志越打越多,view對象也越多。不僅UI繪制頻繁,內(nèi)存也會持續(xù)上升。所以這里想優(yōu)化只能減少view的個數(shù),但是,日志內(nèi)容不能少,個數(shù)怎么減呢?比如把所有內(nèi)容做一個整體,作為一個字符串顯示到控件中,但這樣就不需要listView了,直接一個TextView即可。我們試下這種方案。
第二步,嘗試TextView替換listview實現(xiàn)需求
將布局替換為TextView,通過textView的append屬性來實現(xiàn)追加日志內(nèi)容??梢钥吹叫Ч銎娴暮?,VSYNC信號不會很頻繁,且沒有生成多余的對象。
性能狗測試了一下,CPU占用率為1.7%。
但是TextView也有弊端,對于數(shù)據(jù)的操作沒有l(wèi)istView和recyclerview那么精細(xì)化,如果因為業(yè)務(wù)需求,仍然想用listview怎么辦呢?
第三步,嘗試優(yōu)化listView
實際需求中,如果我們繞不開listView,那么就只能想辦法去優(yōu)化它了。從之前的數(shù)據(jù)來看,是因為UI刷新太頻繁,那么我們降低UI的刷新頻率呢? 這里改動了一下代碼:緩存日志信息,每過500ms才去刷新UI,將緩存的日志顯示到listView中,這樣改完后,看下效果:
有一些好轉(zhuǎn),使用性能狗測試下,看看,結(jié)果CPU占用率為2.4%,也優(yōu)化了不少。
總結(jié)
對于這種問題,利用好工具profiler對程序進(jìn)行分析。能夠快速找到問題原因的基礎(chǔ)在于對工具的熟練程度,對于AS工具的使用,可以直接參考官方文檔的介紹:https://developer.android.google.cn/studio/profile/power-profiler?hl=zh-cn
以上就是解決Android 高CPU占用率的問題的詳細(xì)內(nèi)容,更多關(guān)于Android高CPU占用率的資料請關(guān)注腳本之家其它相關(guān)文章!
- Android、Flutter為不同的CPU架構(gòu)包打包APK(v7a、v8a、x86區(qū)別)
- Python獲取android設(shè)備cpu和內(nèi)存占用情況
- 淺析AndroidStudio3.0最新 Android Profiler分析器(cpu memory network 分析器)
- Android編程實現(xiàn)獲取系統(tǒng)內(nèi)存、CPU使用率及狀態(tài)欄高度的方法示例
- Android獲取設(shè)備CPU核數(shù)、時鐘頻率以及內(nèi)存大小的方法
- 解析Android獲取系統(tǒng)cpu信息,內(nèi)存,版本,電量等信息的方法詳解
- android獲取手機(jī)cpu并判斷是單核還是多核
- Android 輕松獲取CPU型號的方法
相關(guān)文章
Android藍(lán)牙服務(wù)查找附近設(shè)備分析探索
這篇文章主要介紹了Android藍(lán)牙服務(wù)實現(xiàn)查找附近設(shè)備,了解內(nèi)部原理是為了幫助我們做擴(kuò)展,同時也是驗證了一個人的學(xué)習(xí)能力,如果你想讓自己的職業(yè)道路更上一層樓,這些底層的東西你是必須要會的2023-01-01Android?Flutter在點(diǎn)擊事件上添加動畫效果實現(xiàn)全過程
這篇文章主要給大家介紹了關(guān)于Android?Flutter在點(diǎn)擊事件上添加動畫效果實現(xiàn)的相關(guān)資料,通過實例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)Android具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2023-03-03為Android系統(tǒng)添加config.xml 新配置的設(shè)置
這篇文章主要介紹了為Android系統(tǒng)添加config.xml 新配置的設(shè)置,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03android判斷phonegap是否聯(lián)網(wǎng)且加載super.loadUrl網(wǎng)址
android判斷phonegap是否聯(lián)網(wǎng)動態(tài)加載super.loadUrl網(wǎng)址,接下來本文所提供的知識會幫助你解決以上問題,感興趣的你可不要錯過了哈2013-02-02Android App開發(fā)中RecyclerView控件的基本使用教程
這篇文章主要介紹了Android App開發(fā)中RecyclerView控件的基本使用教程,RecyclerView在Android 5.0之后伴隨著Material Design出現(xiàn),管理布局方面十分強(qiáng)大,需要的朋友可以參考下2016-04-04