轉(zhuǎn)載:https://blog.csdn.net/haoxuhong/article/details/80599176
安卓大軍浩浩蕩蕩口注,發(fā)展已近十個年頭,技術(shù)優(yōu)化月新日異君珠,如今Android 9.0 代號P都發(fā)布了寝志,Android系統(tǒng)性能已經(jīng)非常流暢了。但是策添,到了各大廠商手里材部,改源碼自定系統(tǒng),使得Android原生系統(tǒng)變得魚龍混雜唯竹。另外乐导,到了不同層次的開發(fā)工程師手里,因為技術(shù)水平的參差不齊浸颓,即使很多手機在跑分軟件性能非常高物臂,打開應(yīng)用依然存在卡頓現(xiàn)象旺拉。另外,隨著產(chǎn)品內(nèi)容迭代棵磷,功能越來越復(fù)雜账阻,UI頁面也越來越豐富,也成為流暢運行的一種阻礙泽本。綜上所述淘太,對APP進(jìn)行性能優(yōu)化已成為開發(fā)者該有的一種綜合素質(zhì),也是開發(fā)者能夠完成高質(zhì)量應(yīng)用程序的重要考核之一规丽。
(一)網(wǎng)易開源的Emmagee ,https://github.com/NetEase/Emmagee? ?
????Emmagee(機關(guān)槍)是網(wǎng)易杭州研究院QA團(tuán)隊開發(fā)的一個簡單易上手的Android性能監(jiān)測小工具赌莺,主要用于監(jiān)控單個App的CPU冰抢,內(nèi)存,流量艘狭,啟動耗時挎扰,電量,電流等性能狀態(tài)的變化巢音,且用戶可自定義配置監(jiān)控的頻率以及性能的實時顯示遵倦,并最終生成一份性能統(tǒng)計文件。對于手游實時分析CPU和內(nèi)存占比幫助非常大官撼。
(1)優(yōu)勢
開源梧躺;
無需root權(quán)限;
使用方便傲绣;
實時展示數(shù)據(jù)掠哥;
CSV格式保存性能數(shù)據(jù),方便轉(zhuǎn)換為其它格式秃诵;
自定義采集頻率续搀;
支持2.2以及以上版本。(由于Google 安全限制菠净,在7.0版本手機不支持禁舷,找個低版本手機去測就完了)
(2)檢測案例
1、在GitHub下載安裝包Apk
2嗤练、運行Emmagee.app榛了。可以設(shè)置采集頻率煞抬。
3霜大、點擊APP"測試報告"查看,也可以配置郵件下發(fā)CSV文件革答。而我選擇盜取文件到電腦上用Excel表格看战坤。
(本地內(nèi)部存儲Emmagee目錄”storage\sdcard0\Emmagee\某日期時間_APP包名.csv”的文件曙强,即為監(jiān)控數(shù)據(jù))
[objc]view plaincopy
$?adb?shell????//回車??
$?cd?storage/sdcard0/Emmagee/????//回車??
$?ls//回車?,結(jié)果如下:??
20180605154517_com.daojia.csv??
20180605160747_me.ele.csv??
*手機導(dǎo)出的csv文件出現(xiàn)亂碼途茫,原因是由于導(dǎo)出的CSV文件編碼為UTF-8 碟嘴。解決辦法:(Windows)使用記事本打開另存為“ANSI編碼”的CSV格式文件即可。(Mac OS)文本編輯打開重新保存即可囊卜。
上面分別是對到家點餐APP娜扇、餓了么點餐APP的CSV檢測數(shù)據(jù)。移動文件到電腦Excel打開查看:
(二)騰訊開源的GT栅组,https://github.com/TencentOpen/GT
(1)什么是GT?
GT(隨身調(diào))安卓/IOS手機端調(diào)測組件雀瓢,用于APP的性能測試、競品測試及僅憑一臺手機即可進(jìn)行App測試玉掸。利用GT刃麸,僅憑一部手機,無需連接電腦司浪,您即可對APP進(jìn)行快速的性能測試(CPU泊业、內(nèi)存、流量啊易、電量吁伺、幀率/流暢度等)、 開發(fā)日志的查看认罩、Crash日志查看箱蝠、網(wǎng)絡(luò)數(shù)據(jù)包的抓取、APP內(nèi)部參數(shù)的調(diào)試垦垂、真機代碼耗時統(tǒng)計等等;更重要的是牙瓢,您可以在任意真實場所劫拗、 任何時候做如上的系列事情,這就是“APP的場測”矾克。如果您覺得GT提供的功能還不夠滿足您的需要页慷, 您還可以利用GT提供的基礎(chǔ)API自行開發(fā)有特殊功能的GT插件(目前,僅iOS版支持)胁附, 幫助您解決更加復(fù)雜的APP調(diào)試酒繁、測試問題。
(2)如何使用控妻?
????GT支持iOS和Android兩個手機平臺州袒,其中: Android版由一個可直接安裝的GT控制臺APP 和GT SDK插件擴(kuò)展檢測。GT控制臺可以獨立安裝使用弓候,SDK需嵌入被調(diào)測的應(yīng)用郎哭、并利用GT控制臺進(jìn)行信息展示和參數(shù)修改他匪。 iOS版是一個Framework包,必須嵌入APP工程夸研,編譯出帶GT的APP才能使用邦蜜;iPhone和iPad應(yīng)用都能支持。
此處以Android版GT控制臺APP 檢測主功能為案例亥至,簡要介紹使用步驟:
1悼沈、應(yīng)用寶下載GT.APP,安裝運行GT姐扮。
2井辆、選擇應(yīng)用 ? ? ? ? ? ? ? ? ? ? ? ? ??????????????????????????????? ? ? ? ??? ? ? ??
3、選擇關(guān)注的監(jiān)控數(shù)據(jù) ??????????????????? ? 4溶握、結(jié)果展示
(三)科大訊飛的iTest杯缺,http://www.liqucn.com/rj/410791.shtml
iTest官方介紹:
該工具由科大訊飛測試技術(shù)部開發(fā),在多個項目中成功應(yīng)用睡榆,具有較高的準(zhǔn)確性和穩(wěn)定性萍肆。它填補了手機端自動化測試的空白,以實用高效為宗旨胀屿,記錄特定應(yīng)用的性能消耗情況塘揣,包括cpu、內(nèi)存宿崭、流量亲铡、電量等信息。效果圖如下所示葡兑。
遺憾本人尋遍全網(wǎng)奖蔓,只能查找下載安裝Apk的地址,查閱其他的相關(guān)介紹和資料太少讹堤。
畢竟科大訊飛在業(yè)界是很有名氣的是訊飛語音吆鹤。
(四)Google的開源Battery Historian,https://github.com/google/battery-historian
文檔是純英文版的洲守,使用需要配置環(huán)境疑务,包括go/java/python/git的安裝與配置。
從github上下載Battery Historian梗醇。經(jīng)過一頓操作后知允,最終效果圖如下。
由于需要花費大量時間和精力成本投入到研究當(dāng)中叙谨,所以后期有機會再補全使用教程温鸽。
使用性能檢查工具唉俗,可以將自身產(chǎn)品與競爭者產(chǎn)品做對比嗤朴,發(fā)現(xiàn)自身的優(yōu)勢的同時配椭,也可以找到自身產(chǎn)品存在的不足之處。那么雹姊,接下來需要思考自身產(chǎn)品如何進(jìn)行性能的優(yōu)化和改進(jìn)的方法股缸。本著人道主義,一切從用戶體驗的角度去思考吱雏,置身處地得把自己當(dāng)做用戶去玩一款應(yīng)用時候會在意些什么呢敦姻?假如飯點將至,需要打開到家APP進(jìn)行點餐歧杏,首先一定不希望镰惦,在瀏覽商家和菜品列表內(nèi)容很豐富的時候遇到卡頓現(xiàn)象,然后千挑萬選后在期待美食將至的心情下準(zhǔn)備下單犬绒,突然遇到閃退崩潰那簡直想卸載到家APP的心都有了旺入。其次就是配送員在配送過程中不希望耗電和耗流量太嚴(yán)重。最后就是版本更新的時候安裝包希望能小一點凯力。
????用戶希望的四個方面需求總結(jié)如下:
穩(wěn)定(內(nèi)存溢出茵瘾、崩潰)
流暢(卡頓)
耗損(耗電、流量)
安裝包(APK瘦身)
????由于Android應(yīng)用的沙箱機制咐鹤,即每一個Android應(yīng)用程序都在它自己的進(jìn)程中運行拗秘,都擁有一個獨立的Dalvik虛擬機實例,系統(tǒng)默認(rèn)給每個應(yīng)用所分配的內(nèi)存大小是有限度的祈惶,例如:華為mate7雕旨,192m ;小米4捧请,128m 凡涩;紅米,128m 血久;三星SM-N7508v:96m突照。Android4.0以后,可以通過在application節(jié)點中設(shè)置屬性android:largeHeap=”true”來設(shè)置最大可分配多少內(nèi)存空間就可以突破一定限制氧吐。但是,當(dāng)系統(tǒng)內(nèi)存太低依然會觸發(fā)LMK(Low Memory Killer)機制末盔,即閃退筑舅、崩潰現(xiàn)象。
以下分享本人總結(jié)Java內(nèi)存分配及Android常見內(nèi)存泄漏分析相關(guān)文章:
了解內(nèi)存如何分配和回收機制的同學(xué)翠拣,對內(nèi)存優(yōu)化會有一定的認(rèn)識和掌握∮蚊ぃ可以借助內(nèi)存分析工具误墓,方便定位內(nèi)存優(yōu)化的代碼蛮粮。
舉個例子,代碼如下所示:
[java]view plaincopy
public?class?CommUtil?{??
private?static?CommUtil?instance;??
private?Context?context;??
private?CommUtil(Context?context)?{??
this.context=context;??
????}??
public?static?CommUtil?getInstance(Context?context){??
if(null==instance){??
instance=new?CommUtil(context);??
????????}??
return?instance;??
????}??
}??
public?class?MainActivity?extends?AppCompatActivity?{??
@Override??
protected?void?onCreate(Bundle?savedInstanceState)?{??
super.onCreate(savedInstanceState);??
????????setContentView(R.layout.activity_main);??
CommUtil?instance?=?CommUtil.getInstance(this);//??
????}??
}??
一個工具類?CommUtil.class 使用創(chuàng)建型設(shè)計模式——單例模式谜慌,在MainActivity.class中引用然想,那么這個單例對象會持有Activity的實例。然后運行起來 欣范,再將手機屏幕旋轉(zhuǎn)幾下变泄。這樣的代碼會造成什么錯誤?
(旋轉(zhuǎn)屏幕的時候 Activity會被銷毀重新創(chuàng)建恼琼,但是這里的單例會持有銷毀Activity的實例就造成內(nèi)存泄漏)
Memory Monitor 工具:
它是Android Studio自帶的一個內(nèi)存監(jiān)視工具妨蛹,它可以很好地幫助我們進(jìn)行內(nèi)存實時分析。通過點擊Android Studio右下角的Memory Monitor標(biāo)簽晴竞,打開工具可以看見較淺藍(lán)色代表free的內(nèi)存蛙卤,而深色的部分代表使用的內(nèi)存從內(nèi)存變換的走勢圖變換,可以判斷關(guān)于內(nèi)存的使用狀態(tài)噩死,例如當(dāng)內(nèi)存持續(xù)增高時颤难,可能發(fā)生內(nèi)存泄漏;當(dāng)內(nèi)存突然減少時甜滨,可能發(fā)生GC等乐严,如下圖所示。
*案例參考
Memory Analyzer 工具:
MAT(Memory Analyzer Tool) 是一個快速衣摩,功能豐富的 Java Heap 分析工具昂验,通過分析 Java 進(jìn)程的內(nèi)存快照 HPROF 分析,從眾多的對象中分析艾扮,快速計算出在內(nèi)存中對象占用的大小既琴,查看哪些對象不能被垃圾收集器回收,并可以通過視圖直觀地查看可能造成這種結(jié)果的對象泡嘴。檢測步驟如下:
(1)(屏幕多次翻轉(zhuǎn)甫恩,出現(xiàn)內(nèi)存持續(xù)增高時)點擊?Dump java Heap就會生成運行內(nèi)存快照hprof文件。
(2)然后將APP完全退出酌予,重新啟動磺箕,打開Android Monitor 再次點擊Dump java Heap 生成一份還沒操作(旋轉(zhuǎn)屏幕)前的內(nèi)存快照hprof文件。現(xiàn)在就已經(jīng)生成好了2份hprof文件抛虫, 一份是沒有旋轉(zhuǎn)過屏幕的 松靡,一份是旋轉(zhuǎn)過屏幕多次的。
(3)然后選中Android Studio 最左邊的Captures 進(jìn)行將hprof文件導(dǎo)出建椰。導(dǎo)出的時候需要選擇保存的目錄以及文件名雕欺。
(4)打開MAT ,導(dǎo)入我們的2個hprof文件 Open File-->選擇文件-->Leak Suspects Report-->Finish:*案例參考
LeakCanary工具:
簡單,傻瓜式操作屠列±材妫可以在GitHup官網(wǎng)查閱https://github.com/square/leakcanary,我們可以在Gradle文件里添加依賴笛洛。這個工具是Square公司在Github開源的夏志。行業(yè)內(nèi)不是有一句話嘛,Square出品必屬精品撞蜂,主流的庫像okhttp盲镶、Picasso、retrofit蝌诡、Dagger等都出自Square之手溉贿。說到這不得不讓我聯(lián)想到一位在Android開發(fā)領(lǐng)域神一般存在的人物,他就是大名鼎鼎的Jake Wharton(杰克.沃頓)浦旱,ButterKnife的創(chuàng)造者宇色,也參與貢獻(xiàn)了Retrofit, okhttp等。
Android Lint 工具:
Android Lint Tool?是Android Sutido種集成的一個Android代碼提示工具颁湖,它可以給你布局宣蠕、代碼提供非常強大的幫助。
硬編碼會提示以級別警告甥捺,例如:在布局文件中寫了三層冗余的LinearLayout布局抢蚀、直接在TextView中寫要顯示的文字、字體大小使用dp而不是sp為單位镰禾,就會在編輯器右邊看到提示皿曲。使用Android Studio的lint可以清除無用的資源文件:點擊菜單欄的Analyze -> Run Inspection by Name, 輸入unused resource。
當(dāng)然以上都是一個簡單的舉例吴侦,Lint的功能非常強大屋休,大家應(yīng)該養(yǎng)成寫完代碼查看Lint的習(xí)慣,這不僅讓你及時發(fā)現(xiàn)代碼種隱藏的一些問題备韧,更能讓你養(yǎng)成良好的代碼風(fēng)格劫樟,要知道,這些Lint提示可都是Google大牛們汗水合智慧的結(jié)晶织堂。
小結(jié)
????影響穩(wěn)定性的原因很多叠艳,比如內(nèi)存使用不合理、代碼異常場景考慮不周全易阳、代碼邏輯不合理等虑绵,都會對應(yīng)用的穩(wěn)定性造成影響。其中最常見的兩個場景是:Crash 和 ANR闽烙,這兩個錯誤將會使得程序無法使用。所以做好Crash監(jiān)控,把崩潰信息黑竞、異常信息收集記錄起來捕发,以便后續(xù)分析;合理使用主線程處理業(yè)務(wù),不要在主線程中做耗時操作很魂,防止ANR程序無響應(yīng)發(fā)生扎酷。
交互是與用戶體驗最直接的方面遏匆,交互場景大概分為四個部分:UI 繪制法挨、應(yīng)用啟動、頁面跳轉(zhuǎn)幅聘、事件響應(yīng)凡纳,如圖:
界面繪制:主要原因是繪制的層級深、頁面復(fù)雜帝蒿、刷新不合理荐糜,由于這些原因?qū)е驴D的場景更多出現(xiàn)在 UI 和啟動后的初始界面以及跳轉(zhuǎn)到頁面的繪制上。
數(shù)據(jù)處理:導(dǎo)致這種卡頓場景的原因是數(shù)據(jù)處理量太大葛超,一般分為三種情況暴氏,一是數(shù)據(jù)在處理 UI 線程,二是數(shù)據(jù)處理占用 CPU 高绣张,導(dǎo)致主線程拿不到時間片答渔,三是內(nèi)存增加導(dǎo)致 GC 頻繁,從而引起卡頓侥涵。
分析:
我們知道Android的繪制步驟是::Measure沼撕、Layout、Draw独令,所以布局的層級越深端朵、元素越多、耗時也就越長燃箭。還有就是Android 系統(tǒng)每隔 16ms 發(fā)出 VSYNC 信號冲呢,觸發(fā)對 UI 進(jìn)行渲染,如果每次渲染都成功招狸,這樣就能夠達(dá)到流暢的畫面所需的 60FPS敬拓。如果某個操作花費的時間是 24ms ,系統(tǒng)在得到 VSYNC 信號時就無法正常進(jìn)行正常渲染裙戏,這樣就發(fā)生了丟幀現(xiàn)象乘凸。那么用戶在 32ms 內(nèi)看到的會是同一幀畫面,無法在 16ms 完成渲染累榜,最終引起刷新不及時营勤。
兩個根本原因:
繪制任務(wù)太重灵嫌,繪制一幀內(nèi)容耗時太長。
主線程太忙葛作,根據(jù)系統(tǒng)傳遞過來的 VSYNC 信號來時還沒準(zhǔn)備好數(shù)據(jù)導(dǎo)致丟幀寿羞。
在Android種系統(tǒng)對View進(jìn)行測量、布局和繪制時赂蠢,都是通過對View數(shù)的遍歷來進(jìn)行操作的绪穆。如果一個View數(shù)的高度太高就會嚴(yán)重影響測量、布局和繪制的速度虱岂。Google也在其API文檔中建議View高度不宜哦過10層【猎海現(xiàn)在版本種Google使用RelativeLayout替代LineraLayout作為默認(rèn)根布局,目的就是降低LineraLayout嵌套產(chǎn)生布局樹的高度第岖,從而提高UI渲染的效率难菌。
布局復(fù)用,使用<include>標(biāo)簽重用layout绍傲;
提高顯示速度扔傅,使用<ViewStub>延遲View加載;
減少層級烫饼,使用<merge>標(biāo)簽替換父級布局猎塞;
注意使用wrap_content,會增加measure計算成本杠纵;
刪除控件中無用屬性荠耽;
過度繪制是指在屏幕上的某個像素在同一幀的時間內(nèi)被繪制了多次。在多層次重疊的 UI 結(jié)構(gòu)中比藻,如果不可見的 UI 也在做繪制的操作铝量,就會導(dǎo)致某些像素區(qū)域被繪制了多次,從而浪費了多余的 CPU 以及 GPU 資源银亲。所以避免過度繪制:
布局上的優(yōu)化慢叨。移除 XML 中非必須的背景,移除 Window 默認(rèn)的背景务蝠、按需顯示占位背景圖片
自定義View優(yōu)化拍谐。使用 canvas.clipRect()來幫助系統(tǒng)識別那些可見的區(qū)域,只有在這個區(qū)域內(nèi)才會被繪制馏段。
UI 布局轩拨。應(yīng)用一般都有閃屏頁,優(yōu)化閃屏頁的 UI 布局院喜,可以通過 Profile GPU Rendering 檢測丟幀情況亡蓉。
啟動加載邏輯優(yōu)化∨缫ǎ可以采用分布加載砍濒、異步加載淋肾、延期加載策略來提高應(yīng)用啟動速度。
數(shù)據(jù)準(zhǔn)備梯影。數(shù)據(jù)初始化分析巫员,加載數(shù)據(jù)可以考慮用線程初始化等策略。
減少刷新次數(shù)甲棍;
縮小刷新區(qū)域;
在實現(xiàn)動畫效果時赶掖,需要根據(jù)不同場景選擇合適的動畫框架來實現(xiàn)感猛。有些情況下,可以用硬件加速方式來提供流暢度奢赂。
????在移動設(shè)備中,電池的重要性不言而喻膳灶,沒有電什么都干不成咱士。對于操作系統(tǒng)和設(shè)備開發(fā)商來說,耗電優(yōu)化一致沒有停止轧钓,去追求更長的待機時間序厉,而對于一款應(yīng)用來說,并不是可以忽略電量使用問題毕箍,特別是那些被歸為“電池殺手”的應(yīng)用弛房,最終的結(jié)果是被卸載。因此而柑,應(yīng)用開發(fā)者在實現(xiàn)需求的同時文捶,需要盡量減少電量的消耗。
????在 Android5.0 以前媒咳,在應(yīng)用中測試電量消耗比較麻煩粹排,也不準(zhǔn)確,5.0 之后專門引入了一個獲取設(shè)備上電量消耗信息的 API:Battery Historian涩澡。Battery Historian 是一款由 Google 提供的 Android 系統(tǒng)電量分析工具顽耳,和Systrace 一樣,是一款圖形化數(shù)據(jù)分析工具筏养,直觀地展示出手機的電量消耗過程斧抱,通過輸入電量分析文件,顯示消耗情況渐溶,最后提供一些可供參考電量優(yōu)化的方法辉浦。
除此之外,還有一些常用方案可提供:
計算優(yōu)化茎辐,避開浮點運算等宪郊。
避免 WaleLock 使用不當(dāng)掂恕。
使用 Job Scheduler。
????應(yīng)用安裝包大小對應(yīng)用使用沒有影響懊亡,但應(yīng)用的安裝包越大,用戶下載的門檻越高乎串,特別是在移動網(wǎng)絡(luò)情況下店枣,用戶在下載應(yīng)用時,對安裝包大小的要求更高叹誉,因此鸯两,減小安裝包大小可以讓更多用戶愿意下載和體驗產(chǎn)品。
常用應(yīng)用安裝包的構(gòu)成长豁,如圖所示:
從圖中我們可以看到:
assets文件夾钧唐。存放一些配置文件、資源文件匠襟,assets不會自動生成對應(yīng)的 ID钝侠,而是通過 AssetManager 類的接口獲取。
res酸舍。res 是 resource 的縮寫帅韧,這個目錄存放資源文件,會自動生成對應(yīng)的 ID 并映射到 .R 文件中父腕,訪問直接使用資源 ID弱匪。
META-INF。保存應(yīng)用的簽名信息璧亮,簽名信息可以驗證 APK 文件的完整性萧诫。
AndroidManifest.xml。這個文件用來描述 Android 應(yīng)用的配置信息枝嘶,一些組件的注冊信息帘饶、可使用權(quán)限等。
classes.dex群扶。Dalvik 字節(jié)碼程序及刻,讓 Dalvik 虛擬機可執(zhí)行,一般情況下竞阐,Android 應(yīng)用在打包時通過 Android SDK 中的 dx 工具將 Java 字節(jié)碼轉(zhuǎn)換為 Dalvik 字節(jié)碼缴饭。
resources.arsc。記錄著資源文件和資源 ID 之間的映射關(guān)系骆莹,用來根據(jù)資源 ID 尋找資源颗搂。
APK瘦身減少安裝包大小的常用方案:
代碼混淆。使用proGuard 代碼混淆器工具幕垦,它包括壓縮丢氢、優(yōu)化傅联、混淆等功能。
資源優(yōu)化疚察。比如使用?Android Lint?刪除冗余資源蒸走,資源文件最少化等。
圖片優(yōu)化貌嫡。比如利用PNG優(yōu)化工具對圖片做壓縮處理比驻。推薦:zopfliPNG
避免重復(fù)功能的庫,如果應(yīng)用在4.0版本以上衅枫,使用WebP圖片格式等嫁艇。
插件化。比如功能模塊放在服務(wù)器上弦撩,按需下載,可以減少安裝包大小论皆。
可以使用微信開源資源文件混淆工具——AndResGuard益楼。一般可以壓縮apk的1M左右大。
????最后說一句感凤,性能優(yōu)化是一個非常具有挑戰(zhàn)性的工作,上面列出很多分析內(nèi)存粒督、優(yōu)化內(nèi)存的方法陪竿,但是真正優(yōu)化工作遠(yuǎn)不止這么簡單,這里只是列舉了一些入門的方法屠橄,而要進(jìn)行完美的內(nèi)存優(yōu)化族跛、內(nèi)存分析絕非一日之功,需要開發(fā)者深厚的技術(shù)功底合耐心