本章主要介紹的是android的性能優(yōu)化。
1.布局優(yōu)化
Android UI渲染機制
在Android中肚医,系統(tǒng)通過VSYNC信號出發(fā)對UI的渲染庸疾、重繪,其間隔時間是16ms梗劫。這個16ms其實就是1000ms中顯示60幀畫面的單位時間(玩游戲的就該知道,大于等于60幀就感覺不到卡頓)截碴。Android系統(tǒng)提供了檢測UI渲染時間的工具梳侨,打開“開發(fā)者選項”,選擇“Profile GPU Rendering”(我的手機是“GPU呈現(xiàn)模式分析”)日丹,選中“On screen as bars”(我的為“在屏幕上顯示為條形圖”)走哺。每一條柱狀線都包括三部分,藍色代表測量繪制Display List的時間哲虾,紅色代表OpenGL渲染Display List所需要的時間丙躏,黃色代表CPU等待GPU處理的時間,中間綠色橫線代表VSYNC時間16ms束凑,需要盡量將所有條形圖都控制在這條綠線之下彼哼。避免Overdraw
過渡繪制會浪費很多CPU、GPU資源湘今,例如系統(tǒng)默認會繪制Activity的背景,而如果再給布局繪制了重疊的背景剪菱,那么默認Activity的背景就屬于無效的過渡繪制摩瞎。Android系統(tǒng)在開發(fā)者選項中提供了這樣一個檢測工具--“Enable GPU Overdraw”。借助它可以判斷Overdraw的次數(shù)孝常。盡量增大藍色的區(qū)域旗们,減少紅色的區(qū)域。優(yōu)化布局層級
在Android中系統(tǒng)對View的測量构灸、布局和繪制都是通過遍歷View樹來進行的上渴,如果View樹太高,就會影響其速度,Google也建議View樹的高度不宜超過10層稠氮。-
避免嵌套過多無用布局
- 使用
<include>
標簽重用Layout:
為了能夠在不同的Layout組件中使用共通UI曹阔,就可以通過<include>
標簽來完成。
- 使用
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="0dp"
android:textSize="20sp"
android:text="this is a common ui">
</TextView>
然后在布局中進行引用:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include
layout="@layout/test"
android:layout_width="100dp"
android:layout_height="50dp" />
</RelativeLayout>
如果你需要在<include>
標簽中覆蓋類似原布局中android:layout_xxxxx
屬性隔披,就必須在<include>
標簽中同時指定android:layout_width
和android:layout_height
屬性赃份。
* 使用`<ViewStub>`實現(xiàn)View的延遲加載
`<ViewStub>`是個非常輕量級的組件,不僅不可視而且大小為0奢米。這個布局在初始化時不需要顯示抓韩,只有在某些情況下才顯示出來。下面是實例代碼:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="not often use" />
</RelativeLayout>
使用<ViewStub>
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ViewStub
android:id="@+id/view_stub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout="@layout/test" />
</RelativeLayout>
ViewStub viewStub= (ViewStub) findViewById(R.id.view_stub);
//下面兩個方法都是用來實現(xiàn)延遲加載的鬓长,區(qū)別是inflate()方法會返回引用的布局谒拴。
viewStub.setVisibility(View.VISIBLE);
View view=viewStub.inflate();
TextView tv= (TextView) view.findViewById(R.id.tv);
<ViewStub>
標簽與設置View.GONE
這種方式的區(qū)別在于<ViewStub>
標簽只在顯示時渲染整個布局,而設置View.GONE
這種方式在初始化時就已經(jīng)加載了涉波,所以相比之下<ViewStub>
更有效率英上。
- Hierarchy Viewer
這是個用來測試布局冗余的工具,具體用法就不做記錄了怠蹂。介紹在此
2.內存優(yōu)化
- 內存介紹
- 寄存器:速度最快的存儲場所善延,因為寄存器位于處理器內部,在程序中無法控制城侧。
- 棧:存放基本類型的數(shù)據(jù)和對象的引用易遣,但對象本身不存放在棧中,而是存放在堆中嫌佑。
- 堆:堆內存用來存放由new創(chuàng)建的對象和數(shù)組豆茫,在堆中分配的內存,由Java虛擬機的自動垃圾回收器(GC)來管理屋摇。
- 靜態(tài)存儲區(qū)域:是指在固定的位置存放應用程序運行時一直存在的數(shù)據(jù)揩魂,Java在內存中專門劃分了一個靜態(tài)存儲區(qū)域來管理一些特殊的數(shù)據(jù)變量如靜態(tài)的數(shù)據(jù)變量。
- 常量池:就是該類型所用到常量的一個有序集合炮温,包括直接常量(基本類型火脉,String)和對其他類型、字段和方法的符號引用柒啤。
- 內存優(yōu)化實例
Bitmap優(yōu)化
Bitmap是造成內存占用過高甚至是OOM的最大威脅倦挂,可以通過以下技巧進行優(yōu)化
① 使用適當分辨率和大小的圖片:例如在圖片列表界面可以使用圖片的縮略圖thumbnails,而在顯示詳細圖片的時候再顯示原圖担巩;或者在對圖像要求不高的地方方援,盡量降低圖片的精度。
② 及時回收內存:一旦使用完Bitmap后涛癌,一定要及時使用bitmap.recycle()
方法釋放內存資源犯戏。自Android3.0后送火,由于Bitmap被放到了堆中,其內存由GC管理先匪,就不需要釋放了种吸。
③ 通過內存緩存LruCache
和DiskLruCache
可以更好地使用Bitmap。代碼優(yōu)化
任何Java類都將占用大約500字節(jié)的內存空間胚鸯,創(chuàng)建一個類的實例會消耗大約15字節(jié)內存骨稿。從代碼的實現(xiàn)上,也可以對內存進行優(yōu)化姜钳。
① 對常量使用static修飾符坦冠。
② 使用靜態(tài)方法,靜態(tài)方法會比普通方法提高15%左右的訪問速度哥桥。
③ 減少不必要的成員變量辙浑,這點在Android Lint工具上已經(jīng)集成檢測了。
④ 減少不必要對象拟糕,使用基礎類型會比使用對象更加節(jié)省資源判呕,同時更應該避免頻繁創(chuàng)建短作用域的變量。
⑤ 盡量不要使用枚舉送滞、少用迭代器侠草。
⑥ 對Cursor
、Receiver
犁嗅、Sensor
边涕、File
等對象,要非常注意對它們的創(chuàng)建褂微、回收和注冊功蜓、反注冊。
⑦ 避免使用IOC框架宠蚂,IOC通常使用注解式撼、反射來進行實現(xiàn),大量使用反射會帶來性能的下降求厕。
⑧ 使用RenderScript著隆、OpenGL來進行非常復雜的繪圖操作。
⑨ 使用SurfaceView來代替View進行大量呀癣、頻繁的繪圖操作旅东。
⑩ 盡量使用視圖緩存,而不是每次都執(zhí)行inflate()
解析視圖十艾。
本章節(jié)后面還介紹了Lint、MemoryMonitor腾节、TraceView忘嫉、MAT等工具來分析內存的使用情況荤牍,這里就不做記錄了!