Android設備做爲一種移動設備,不管是內存仍是CPU的性能都受到了很大的限制,這致使Android程序的性能問題異常突出,隨着產品的不斷更新迭代,對於性能優化提出了更高的要求。本篇文章從穩定性、流暢性、耗損、安裝包大小四個方面對Android開發提供了一些容易上手、切實有效的性能優化方法,爲Android開發中有關性能優化方面的學習提供一個參考。
1.穩定性(解決內存溢出、崩潰等問題),內存優化
(1)Memory Monitor 工具:
Android Studio自帶的一個內存監視工具,它能夠很好地幫助咱們進行內存實時分析。經過點擊Android Studio右下角的Memory Monitor標籤,打開工具能夠看見較淺藍色表明free的內存,而深色的部分表明使用的內存從內存變換的走勢圖變換,能夠判斷關於內存的使用狀態,例如當內存持續增高時,可能發生內存泄漏;當內存忽然減小時,可能發生GC等
(2)Memory Analyzer 工具:
MAT(Memory Analyzer Tool) 是一個快速,功能豐富的 Java Heap 分析工具,經過分析 Java 進程的內存快照 HPROF 分析,從衆多的對象中分析,快速計算出在內存中對象佔用的大小,查看哪些對象不能被垃圾收集器回收,並能夠經過視圖直觀地查看可能形成這種結果的對象。
檢測步驟以下:
(a)屏幕屢次翻轉,出現內存持續增高時。點擊 Dump java Heap就會生成運行內存快照hprof文件。html
(b)而後將APP徹底退出,從新啓動,打開Android Monitor 再次點擊Dump java Heap 生成一份還沒操做(旋轉屏幕)前的內存快照hprof文件。如今就已經生成好了2份hprof文件, 一份是沒有旋轉過屏幕的 ,一份是旋轉過屏幕屢次的。java
(c)而後選中Android Studio 最左邊的Captures 進行將hprof文件導出。導出的時候須要選擇保存的目錄以及文件名。git
(d)打開MAT ,導入咱們的2個hprof文件 Open File-->選擇文件-->Leak Suspects Report-->Finishgithub
能夠經過檢索包名,查看某個類的實例個數和所在內存數據,還能夠查看被引用的內存數據。算法
Objects:實例個數
Shallow Heap:所佔內存大小
Retained Heap:釋放後能回收多少內存數據庫
(3)LeakCanary工具:
簡單,傻瓜式操做。能夠在GitHup官網查閱https://github.com/square/leakcanary,咱們能夠在Gradle文件裏添加依賴。這個工具是Square公司在Github開源的。行業內不是有一句話嘛,Square出品必屬精品,主流的庫像okhttp、Picasso、retrofit、Dagger等都出自Square之手。說到這不得不讓我聯想到一位在Android開發領域神通常存在的人物,他就是大名鼎鼎的Jake Wharton(傑克.沃頓),ButterKnife的創造者,也參與貢獻了Retrofit, okhttp等。canvas
(4)Android Lint 工具:
Android Lint Tool 是Android Sutido種集成的一個Android代碼提示工具,它能夠給你佈局、代碼提供很是強大的幫助。
硬編碼會提示以級別警告,例如:在佈局文件中寫了三層冗餘的LinearLayout佈局、直接在TextView中寫要顯示的文字、字體大小使用dp而不是sp爲單位,就會在編輯器右邊看到提示。使用Android Studio的lint能夠清除無用的資源文件(點擊菜單欄的Analyze -> Run Inspection by Name, 輸入unused resource)。
固然以上都是一個簡單的舉例,Lint的功能很是強大,你們應該養成寫完代碼查看Lint的習慣,這不只讓你及時發現代碼種隱藏的一些問題,更能讓你養成良好的代碼風格,要知道,這些Lint提示可都是Google大牛們汗水合智慧的結晶。
小結
影響穩定性的緣由不少,好比內存使用不合理、代碼異常場景考慮不周全、代碼邏輯不合理等,都會對應用的穩定性形成影響。其中最多見的兩個場景是:Crash 和 ANR,這兩個錯誤將會使得程序沒法使用。因此作好Crash全局監控,處理閃退同時把崩潰信息、異常信息收集記錄起來,以便後續分析;合理使用主線程處理業務,不要在主線程中作耗時操做,防止ANR程序無響應發生。
2.流暢性(卡頓優化)
卡頓的場景一般是發生在用戶交互體驗最直接的方面。影響卡頓的兩大因素,分別是界面繪製和數據處理。
- 界面繪製:主要緣由是繪製的層級深、頁面複雜、刷新不合理,因爲這些緣由致使卡頓的場景更多出如今 UI 和啓動後的初始界面以及跳轉到頁面的繪製上。
- 數據處理:致使這種卡頓場景的緣由是數據處理量太大,通常分爲三種狀況,一是數據在處理 UI 線程,二是數據處理佔用 CPU 高,致使主線程拿不到時間片,三是內存增長致使 GC 頻繁,從而引發卡頓。
卡頓場景大概分爲四個方面,以下圖所示。
分析UI卡頓:緩存
咱們知道Android的繪製步驟是:Measure、Layout、Draw,因此佈局的層級越深、元素越多、耗時也就越長。還有就是Android操做系統每隔 16ms 發出 VSYNC 信號,觸發對 UI 進行渲染,若是每次渲染都成功,這樣就可以達到流暢的畫面所需的 60FPS。若是某個操做花費的時間是 24ms ,系統在獲得 VSYNC 信號時就沒法正常進行正常渲染,這樣就發生了丟幀現象。那麼用戶在 32ms 內看到的會是同一幀畫面,沒法在 16ms 完成渲染,最終引發刷新不及時。性能優化
總結以上,兩個根本緣由:一、繪製任務過重,繪製一幀內容耗時太長;二、主線程太忙,根據系統傳遞過來的 VSYNC 信號來時,還沒準備好數據,致使丟幀。微信
(1)佈局優化
在Android種系統對View進行測量、佈局和繪製時,都是經過對View數的遍從來進行操做的。若是一個View數的高度過高就會嚴重影響測量、佈局和繪製的速度。Google也在其API文檔中建議View高度不宜哦過10層。如今版本種Google
使用RelativeLayout替代LineraLayout做爲默認根佈局,目的就是下降LineraLayout嵌套產生布局樹的高度,從而提升UI渲染的效率。
(2)繪製優化
過分繪製是指在屏幕上的某個像素在同一幀的時間內被繪製了屢次。在多層次重疊的 UI 結構中,若是不可見的 UI 也在作繪製的操做,就會致使某些像素區域被繪製了屢次,從而浪費了多餘的 CPU 以及 GPU 資源。如何避免過分繪製?
(3)啓動優化
應用通常都有閃屏頁SplashActivity,優化閃屏頁的 UI 佈局,能夠經過 Profile GPU Rendering 檢測丟幀狀況。
(另外,還能夠IDE自帶的一款UI繪製檢測圖形化數據分析工具 Systrace ,4.0版本以上版本可使用。)
閃屏頁的存在能夠說就是啓動優化,一般在閃屏頁延遲2秒跳轉到主界面,可是在進入首頁的時候,首頁複雜的View渲染以及必須在UI線程執行的業務邏輯,必然拖慢了啓動速度。啓動閃屏頁雖然簡單執行快,首頁卻複雜執行慢,應用啓動前輕後重。
因此要啓動加載邏輯優化。能夠採用分佈加載、異步加載、延期加載策略來提升應用啓動速。例如,把SplashActivity改爲SplashFragment,應用程序的入口變成MainActivity,在MainActivity中先展現SplashFragment,顯示完畢後再移除SplashFragment。這樣,在SplashFragment的2S的友好時間內進行數據準備的同時,首頁的View就可以被加載,首頁的業務邏輯就可以被執行。在閃屏頁窗口加載完畢後,咱們加載activity_main的佈局,考慮到這個佈局有可能比較複雜,耽誤View的解析時間,能夠採用ViewStub的形式進行懶加載。
(4)刷新優化
(5)動畫優化
須要實現動畫效果時,須要根據不一樣場景選擇合適的動畫框架來實現。有些狀況下,能夠用硬件加速方式來提供流暢度下降動畫卡頓。
3.耗損(耗電、流量消耗)
3.1耗電優化
在移動設備中,電池的重要性天然不言而喻,若是手機沒電了應用功能技術實現再怎麼牛逼,用戶也什麼都幹不成。對於Android操做系統和設備各大開發商來講,對手機耗電的優化從沒有中止過,不斷地追求更長的待機時間。而對於開發一款應用來講,毫不能夠忽略電量耗損的問題,被歸爲「電池殺手」的應用,最終的結果無疑是走向被用戶卸載的道路。好比,有些應用爲了保持應用進程長期在後臺存活,使用各類不合理進程保活方案,破壞操做系統「生態平衡」,致使用戶電量嚴重耗損,雖然這種流氓開發行爲並不違法吧,可是也屬於不道德的行爲,也一樣會被同行所被鄙視的行爲。
在 Android5.0 之前,關於應用電量消耗的測試即麻煩又不許確,而5.0 以後Google專門引入了一個獲取設備上電量消耗信息的API—— Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系統電量分析工具,直觀地展現出手機的電量消耗過程,經過輸入電量分析文件,顯示消耗狀況。
最後提供一些可供參考耗電優化的方法:
浮點運算:計算機裏整數和小數形式就是按普通格式進行存儲,例如102四、3.1415926等等,這個沒什麼特色,可是這樣的數精度不高,表達也不夠全面,爲了可以有一種數的通用表示法,就發明了浮點數。浮點數的表示形式有點像科學計數法(*.*****×10^***),它的表示形式是0.*****×10^***,在計算機中的形式爲 .***** e ±***),其中前面的星號表明定點小數,也就是整數部分爲0的純小數,後面的指數部分是定點整數。利用這樣的形式就能表示出任意一個整數和小數,例如1024就能表示成0.1024×10^4,也就是 .1024e+004,3.1415926就能表示成0.31415926×10^1,也就是 .31415926e+001,這就是浮點數。浮點數進行的運算就是浮點運算。浮點運算比常規運算更復雜,所以計算機進行浮點運算速度要比進行常規運算慢得多。
Wake Lock是一種鎖的機制,主要是相對系統的休眠而言的,,只要有人拿着這個鎖,系統就沒法進入休眠意思就是個人程序給CPU加了這個鎖那系統就不會休眠了,這樣作的目的是爲了全力配合咱們程序的運行。有的狀況若是不這麼作就會出現一些問題,好比微信等及時通信的心跳包會在熄屏不久後中止網絡訪問等問題。因此微信裏面是有大量使用到了Wake_Lock鎖。系統爲了節省電量,CPU在沒有任務忙的時候就會自動進入休眠。有任務須要喚醒CPU高效執行的時候,就會給CPU加Wake_Lock鎖。你們常常犯的錯誤,咱們很容易去喚醒CPU來工做,可是很容易忘記釋放Wake_Lock。
在Android 5.0 API 21 中,google提供了一個叫作JobScheduler API的組件,來處理當某個時間點或者當知足某個特定的條件時執行一個任務的場景,例如當用戶在夜間休息時或設備接通電源適配器鏈接WiFi啓動下載更新的任務。這樣能夠在減小資源消耗的同時提高應用的效率。
3.2流量優化
3.2.1 對通信錄式、我的信息式的數據進行數據庫的存儲;
3.2.2 對瀏覽類的數據進行三級緩存
4.安裝包(縮小apk大小)