1、硬件耗電
主要有:
1、屏幕
2、CPU
3、WLAN
4、感應器
5、GPS(目前我們沒有)
電量其實是目前手持設備最寶貴的資源之一,大多數設備都需要不斷的充電來維持繼續使用。不幸的是,對于開發者來說,電量優化是他們最后才會考慮的的事情。但是可以確定的是,千萬不能讓你的應用成為消耗電量的大戶
2、參考
2.1
2.2
Purdue University研究了最受歡迎的一些應用的電量消耗,平均只有30%左右的電量是被程序最核心的方法例如繪制圖片,擺放布局等等所使用掉的,剩下的70%左右的電量是被上報數據,檢查位置信息,定時檢索后臺廣告信息所使用掉的。如何平衡這兩者的電量消耗,就顯得非常重要了。
2.3
2.4
3、WIFI耗電
前段時間做的省電主要是針對wifi的,三種情況下效果很明顯:
1、桌面待機
2、任何應用Home鍵待機
3、用瀏覽器或者愛奇藝看視頻待機,這種效果相當的明顯,完全秒殺
小米平板;同時待機86個小時小米平板(6700毫安):沒電自動關機
K1平板(4060毫安) :還剩68%
這樣處理過后,平板待機時間至少是10天
4、后臺應用
目前我們做的做法是后臺只保留一個后臺程序。后期我們會考慮待機一定時間后,我們會把后臺程序清理掉,這樣會更省電。
5、APP提高續航
總體原則:提高性能
1、不作沒有必要的工作
2、盡量避免內存分配
通常來講,盡量避免創建短時臨時對象.少的對象創建意味著低頻的垃圾回收。而這對于用戶體驗產生直接的影響。
例:避免內部的Getters/Setters
在源生語言像C++中,通常做法是用Getters(i=getCount())代替直接字段訪問(
i=mCount)。這是C++中一個好的習慣,因為編譯器會內聯這些訪問,并且如果需要約束或者調試這些域的訪問,你可以在任何時間添加代碼。
而在Android中,這不是一個好的做法。虛方法調用的代價比直接字段訪問高昂許多。通常根據面向對象語言的實踐,在公共接口中使用Getters和Setters是有道理的,但在一個字段經常被訪問的類中宜采用直接訪問。
無JIT時,直接字段訪問大約比調用getter訪問快3倍。有JIT時(直接訪問字段開銷等同于局部變量訪問),要快7倍。在Froyo版本中確實如此,但以后版本可能會在JIT中改進Getter方法的內聯。
6、布局
總體原則:控件盡量少、盡量減少布局層次
1、Textview +Imageview → Textview+icon(android:drawableXXX)
2、多個LinearLayout→單個RelativeLayout
3、使用 標簽來減少視圖層級結構
4、通過 標簽來重用layout代碼
5、Layout_weight使用時,android:layout_width或者android:layout_height值盡量為0,而不是自適應,為什么?
…
View渲染流程
7、WakeLock
盡量減少喚醒屏幕的次數與持續的時間(屏幕是用電大戶),用WakeLock來處理喚醒的問題,能夠正確執行喚醒操作并根據設定及時關閉操作進入睡眠狀態,使用wakelock.acquice() 方法,一定要加上超時處理(例如釋放鎖)。
使用場景:Android中通過各種Lock鎖對電源進?行控制,比如保持通信和后臺續連。
另一種思路:
不用冒著忘記釋放Wakelock的風險,交給系統處理,也不用在manifest中設置權限,只在布局文件XML聲明即可,當然也可以用函數:View.setKeepScreenOn()方法控制即可。
8、優化網絡
1、設置網絡超時時間包括連接超時和請求超時
2、觸發網絡請求的操作,每次都會保持無線信號持續一段時間,我們可以把零散的網絡請求打包進行一次操作,避免過多的無線信號引起的電量消耗(例如APP的數據采集)。比如我們的大數據和推送等應用。
3、如果沒有網絡連接,你的應用跳過網絡操作;只在有網絡連接并且無漫游的情況下更新數據;
4、選擇兼容的數據格式,把含有文本數據和二進制數據的請求全部轉化成二進制數據格式請求;
5、使用高效的轉換工具,多考慮使用流式轉換工具,少用樹形的轉換工具;
很明顯,使用流的方式解析效率要高一些,因為DOM解析是在對整個文檔讀取完后,再根據節點層次等再組織起來。而流的方式是邊讀取數據邊解析,數據讀取完后,解析也就完畢了。
在數據格式方面,JSON和Protobuf效率明顯比XML好很多,XML和JSON大家都很熟悉,Protobuf是Google提出的,一種語言無關、平臺無關、擴展性好的用于通信協議、數據存儲的結構化數據串行化方法。
從上面的圖中我們可以得出結論就是盡量使用SAX等邊讀取邊解析的方式來解析數據,針對移動設備,最好能使用JSON之類的輕量級數據格式為佳。
6、如果可以的話,請使用framework的GZIP庫來壓縮文本數據以高效使用CPU資源。
9、調整定時更新的頻率
int alarmType = AlarmManager.ELAPSED_REALTIME;
long interval = AlarmManager.INTERVAL_HOUR;
long start = System.currentTimeMillis() + interval;
alarmManager.setInexactRepeating(alarmType, start, interval, pi);
如果可以,請設置提醒的類型為ELAPSED_REALTIME or RTC而不是_WAKEUP;這樣在系統睡眠的時候不會喚醒CPU。
10、數據庫使用事務
1、首先Android數據庫操作(特別是寫操作)是非常慢的,將所有操作打包成一個事務能大大提高處理速度。
2、在setTransactionSuccessful和endTransaction之間不進行任何數據庫操作。
11、Adapter標準
12、廣播接收
1、盡量能不用靜態注冊就不要靜態注冊
2、盡量在onResume()和onPause()中進行注冊與注銷
3、廣播用完后一定要記得注銷
13、回收對象
JVM的回收機制給開發人員帶來很大的好處,不用時刻處理對象的分配與回收,可以更加專注于更加高級的代碼實現。相比起Java,C與C++等語言具備更高的執行效率,他們需要開發人員自己關注對象的分配與回收。
雖然Java有自動回收的機制,這不意味著Java中不存在內存泄漏的問題,在一個龐大的系統當中,還是免不了經常發生部分對象忘記回收的情況,而內存泄漏會很容易導致嚴重的性能問題。
內存泄漏指的是那些程序不再使用的對象無法被GC識別,這樣就導致這個對象一直留在內存當中,占用了寶貴的內存空間。顯然,這還使得每級Generation的內存區域可用空間變小,GC就會更容易被觸發,從而引起性能問題。
尋找內存泄漏并修復這個漏洞是件很棘手的事情,你需要對執行的代碼很熟悉,清楚的知道在特定環境下是如何運行的,然后仔細排查。
原始JVM中的GC機制在Android中得到了很大程度上的優化。Android里面是一個三級Generation的內存模型,最近分配的對象會存放在Young Generation區域,當這個對象在這個區域停留的時間達到一定程度,它會被移動到Old Generation,最后到Permanent Generation區域。
大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。從設計師的角度,他們希望App能夠有更多的動畫,圖片等時尚元素來實現流暢的用戶體驗。但是Android系統很有可能無法及時完成那些復雜的界面渲染操作。Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps,這意味著程序的大多數操作都必須在16ms內完成。
我們通常都會提到60fps與16ms,可是知道為何會是以程序是否達到60fps來作為App性能的衡量標準嗎?這是因為人眼與大腦之間的協作無法感知超過60fps的畫面更新。
12fps大概類似手動快速翻動書籍的幀率,這明顯是可以感知到不夠順滑的。24fps使得人眼感知的是連續線性的運動,這其實是歸功于運動模糊的效果。24fps是電影膠圈通常使用的幀率,因為這個幀率已經足夠支撐大部分電影畫面需要表達的內容,同時能夠最大的減少費用支出。但是低于30fps是無法順暢表現絢麗的畫面內容的,此時就需要用到60fps來達到想要的效果,當然超過60fps是沒有必要的。
16=1000/60
通常來說,單個的GC并不會占用太多時間,但是大量不停的GC操作則會顯著占用幀間隔時間(16ms)。如果在幀間隔時間里面做了過多的GC操作,那么自然其他類似計算,渲染等操作的可用時間就變得少了。
Android對GC做了大量的優化操作,雖然執行GC操作的時候會暫停其他任務,可是大多數情況下,GC操作還是相對很安靜并且高效的。但是如果我們對內存的使用不恰當,導致GC頻繁執行,這樣就會引起不小的性能問題
有些對象的回收不能依賴系統GC,比如:XmlPullParserFactory and BitmapFactory …
14、onDraw方法
自定義View中的onDraw方法也需要引起注意,每次屏幕發生繪制以及動畫執行過程中,onDraw方法都會被調用到,避免在onDraw方法里面執行復雜的操作,避免創建對象。對于那些無法避免需要創建對象的情況,我們可以考慮對象池模型,通過對象池來解決頻繁創建與銷毀的問題,但是這里需要注意結束使用之后,需要手動釋放對象池中的對象。
但是不幸的是,對于那些過于復雜的自定義的View(重寫了onDraw方法),Android系統無法檢測具體在onDraw里面會執行什么操作,系統無法監控并自動優化,也就無法避免Overdraw了。但是我們可以通過canvas.clipRect()來幫助系統識別那些可見的區域。這個方法可以指定一塊矩形區域,只有在這個區域內才會被繪制,其他的區域會被忽視。這個API可以很好的幫助那些有多組重疊組件的自定義View來控制顯示的區域。同時clipRect方法還可以幫助節約CPU與GPU資源,在clipRect區域之外的繪制指令都不會被執行,那些部分內容在矩形區域內的組件,仍然會得到繪制。
15、工具
15.1、hierarchyviewer
15.2、Lint(官方代碼優化利器)
Android Lint是SDK Tools 16 (ADT 16)之后才引入的工具,通過它對Android工程源代碼進行掃描和檢查,可發現潛在的問題,以便程序員及早修正這個問題。Android Lint提供了命令行方式執行,還可與IDE(如Eclipse)集成,并提供了html形式的輸出報告。
官網:http://tools.android.com/tips/lint
16、其他
1、動畫
2、傳感器
3、清理緩存和垃圾文件
.
.
.
覺得本文對您有用,麻煩點贊、關注、收藏,您的肯定是我創作的無限動力,謝謝!!!