Android性能優化
Android不可能無限制的使用內存和CPU資源,過多的使用內存會致使內存溢出,即OOM。android
而過多的使用CPU資源,一般是指作大量的耗時任務,會致使手機變的卡頓甚至出現程序沒法響應的狀況,即ANR。緩存
15.1.1佈局優化
一、怎樣進行佈局優化?性能優化
- 首先刪除佈局中沒用的控件和層級
- 其次有選擇的使用性能較低的ViewGroup。
- 佈局優化的還有一種手段是採用標籤、標籤、ViewStub。標籤主要用於佈局重用,標籤通常和配合使用,它可以減小減小布局的層級,而ViewStub則提供了按需載入的功能,當需要時纔會將ViewStub中的佈局載入到內存。提升了程序的初始化效率。
二、標籤僅僅支持android:layout_開頭的屬性,android:id屬性例外。markdown
三、ViewStub繼承了View。它很是輕量級且寬/高都是0,所以它自己並不參與不論什麼的佈局和繪製過程。ViewStub的意義在於按需載入所需的佈局文件,在實際開發中。有很是多佈局文件在正常狀況下不會顯示,比方網絡異常時的界面,這個時候就沒有必要在整個界面初始化的時候將其載入起來,經過ViewStub就可以作到在使用的時候再載入,提升了程序初始化的性能。網絡
例如如下所看到的,android:id是ViewStub的id,而android:inflatedId是佈局的根元素的id。數據結構
<ViewStub android:id="@+id/xxx"
android:inflatedId="@+id/yyy"
android:layout="@layout/zzz"
...
</ViewStub>
需要載入ViewStub中的佈局的時候,可以依照例如如下兩種方式進行:併發
((ViewStub)findViewById(R.id.xx)).setVisibility(View.VISIBLE)
或者工具
View importPanel = ((ViewStub)findViewById(R.id.stub_import)).inflate()
15.1.1繪製優化
繪製優化是指View的onDraw方法要避免運行大量的操做:佈局
- 在onDraw中不要建立新的局部對象。這是因爲onDraw方法可能會被頻繁調用,這樣就會在一瞬間產生大量的暫時對象,這不只佔用了過多的內存而且還會致使系統更加頻繁的gc,減小了程序的運行效率。
- onDraw方法中不要指定耗時任務,也不能運行成千上萬次的循環操做,View的繪製幀率保證60fps是最佳的。這就要求每幀的繪製時間不超過16ms,儘管程序很是難保證16ms這個時間,但是儘可能減小onDraw方法的複雜度老是切實有效的。
15.1.3內存泄漏優化
可能致使內存泄漏的場景很是多,好比靜態變量、單例模式、屬性動畫、AsyncTask、Handler等等post
15.1.4響應速度優化和ANR日誌分析
- ANR出現的狀況:Activity假設5秒內沒有響應屏幕觸摸事件或者鍵盤輸入事件就會ANR。而BroadcastReceiver假設10s沒有運行完操做也會出現ANR。
- 當一個進程發生了ANR以後,系統會在/data/anr文件夾下建立一個文件traces.txt,經過分析這個文件就能定位ANR的緣由。
15.1.5ListView和Bitmap優化
- ListView優化:採用ViewHolder並避免在getView方法中運行耗時操做。依據列表的滑動狀態來繪製任務的運行效率;可以嘗試開啓硬件加速期來使ListView的滑動更加流暢。
- Bitmap優化:依據需要對圖片進行採樣,主要是經過BitmapFactory.Options來依據需要對圖片進行採樣,採樣主要用到了BitmapFactory.Options的inSampleSize參數。
15.1.6線程優化
- 採用線程池,避免程序中存在大量的Thread。線程池可以重用內部的線程,從而避免了線程的建立和銷燬所帶來的性能開銷,同一時候線程池還能有效的控制線程池的最大併發數,避免大量的線程因互相搶佔系統資源從而致使堵塞現象的發生。
15.1.7一些性能優化建議
- 避免 建立過多的對象
- 不要過多的使用枚舉,枚舉佔用的內存空間要比整形大
- 常量請用static final來修飾
- 使用一些Android特有的數據結構,比方SparseArray和Pair等。它們都具備更好的性能
- 適當使用軟引用和弱引用
- 採用內存緩存和磁盤緩存
- 儘可能採用靜態內部類,這樣可以避免潛在的因爲內部類而致使的內存泄漏
15.2內存泄漏分析之MAT工具
MAT是功能強大的內存分析工具,主要有Histograms和Dominator Tree等功能
15.3提升程序的可維護性
- 命名要規範,要能正確地傳達出變量或者方法的含義。少用縮寫。關於變量的前綴可以參考Android源代碼的命名方式,比方私有成員以m開頭,靜態成員以s開頭。常量則所實用大寫字母表示,等等。
- 代碼的排版上需要留出合理的空白來區分不一樣的代碼塊。當中同類變量的聲明要放在一塊兒,兩類變量之間要留出一行空白做爲區分。
- 合理的命名風格,僅在很是關鍵的代碼加入凝視。