注:你的app為什么會(huì )卡?為什么占用大內存?應該怎么解決?這篇文章會(huì )給你答案。

20 條建議

1. itmap的合理使用:使用Bitmap過(guò)后,就需要及時(shí)的調用recycle()方法來(lái)釋放Bitmap占用的內存空間,而不要等Android系統來(lái)進(jìn)行釋放。

代碼示例:

// 先判斷是否已經(jīng)回收

if(bitmap != null && !bitmap.isRecycled()){

bitmap.recycle();

bitmap = null;

}

System.gc();

2. 對常量使用static final修飾符

static final int intVal = 42;

static final String strVal = “Hello, world!”;

將一個(gè)方法或類(lèi)聲明為final不會(huì )帶來(lái)性能的提升,但是會(huì )幫助編譯器優(yōu)化代碼。舉例說(shuō),如果編譯器知道一個(gè)getter方法不會(huì )被重載,那么編譯器會(huì )對其采用內聯(lián)調用。

3. 靜態(tài)方法代替虛擬方法

如果不需要訪(fǎng)問(wèn)某對象的字段,將方法設置為靜態(tài),調用會(huì )加速15%到20%。這也是一種好的做法,因為你可以從方法聲明中看出調用該方法不需要更新此對象的狀態(tài)。

4. 減少不必要的全局變量

盡量避免static成員變量引用資源耗費過(guò)多的實(shí)例,比如Context,因為Context的引用超過(guò)它本身的生命周期,會(huì )導致Context泄漏。所以盡量使用Application這種Context類(lèi)型。 可以通過(guò)調用Context.getApplicationContext()或 Activity.getApplication()輕松得到Application對象。

5. 避免創(chuàng )建不必要的對象: 就是避免創(chuàng )建短命的臨時(shí)對象。減少對象的創(chuàng )建就能減少垃圾收集,進(jìn)而減少對用戶(hù)體驗的影響。

例如:頻繁操作一個(gè)字符串時(shí),使用StringBuffer代替String。

對于所有所有基本類(lèi)型的組合:int數組比Integer數組好,這也概括了一個(gè)基本事實(shí),兩個(gè)平行的int數組比 (int,int)對象數組性能要好很多。.避免使用浮點(diǎn)數

通常的經(jīng)驗是,在A(yíng)ndroid設備中,浮點(diǎn)數會(huì )比整型慢兩倍。

7. 使用實(shí)體類(lèi)比接口好

假設你有一個(gè)HashMap對象,你可以將它聲明為HashMap或者M(jìn)ap:

Map map1 = new HashMap();

HashMap map2 = new HashMap();

哪個(gè)更好呢?

按照傳統的觀(guān)點(diǎn)Map會(huì )更好些,因為這樣你可以改變他的具體實(shí)現類(lèi),只要這個(gè)類(lèi)繼承自Map接口。傳統的觀(guān)點(diǎn)對于傳統的程序是正確的,但是它并不適合嵌入式系統。調用一個(gè)接口的引用會(huì )比調用實(shí)體類(lèi)的引用多花費一倍的時(shí)間。如果HashMap完全適合你的程序,那么使用Map就沒(méi)有什么價(jià)值。如果有些地方你不能確定,先避免使用Map,剩下的交給IDE提供的重構功能好了。(當然公共API是一個(gè)例外:一個(gè)好的API常常會(huì )犧牲一些性能)

8. 訪(fǎng)問(wèn)成員變量比訪(fǎng)問(wèn)本地變量慢得多

for循環(huán):不要在for的第二個(gè)條件中調用任何方法

反例:for(int i =0; i < this.getCount(); i++) {}

正例:int count = this.mCount;  int count = this.getCount();

for(int i =0; i < count; i++)  {

}

9. 資源類(lèi)對象在不使用的時(shí)候,應該及時(shí)關(guān)閉它們,方便它們的緩存數據能夠及時(shí)回收。

例如:Cursor、File文件等都需要在finally中關(guān)閉資源性對象,避免在異常情況下資源對象未被釋放的隱患

10. 注冊廣播接收器、注冊觀(guān)察者等需要在不使用的時(shí)候取消注冊。

例如:假設在A(yíng)ctivity中,監聽(tīng)系統的電話(huà)服務(wù),可以在A(yíng)ctivity中定義一個(gè)PhoneStateListener的對象,同時(shí)將它注冊到TelephoneManager服務(wù)中。對于A(yíng)ctivity對象,理論上要求Activity退出后該Activity的對象就會(huì )被釋放掉。但是如果在釋放Activity對象時(shí),忘記取消之前注冊的PhoneStateListener對象,則會(huì )導致Activity無(wú)法被GC回收。如果不斷的進(jìn)出這個(gè)Activity,則最終會(huì )由于大量的Activity對象沒(méi)有辦法被回收而引起頻繁的GC情況,甚至導致Out Of Memory。

11. 有效的利用系統自帶的資源,Android系統內置了大量的資源,比如字串、顏色定義、常用Icon圖片、動(dòng)畫(huà)樣式、及簡(jiǎn)單的布局,沒(méi)有特殊要求,資源可以在程序中直接引用。這樣不僅減少內存的開(kāi)銷(xiāo),還可以減少apk的大小。

12. 視圖復用,使用ViewHolder實(shí)現ConvertView復用,這基本上是所有容器控件的處理方式,如ListView、GridView等。

13. 使用最優(yōu)的數據類(lèi)型,比較少的對象數時(shí),ArrayMap替換HashMap的使用,避免使用枚舉,枚舉變量非常方便,但不幸的是它會(huì )犧牲執行的速度和并大幅增加文件體積。

14. 圖片內存優(yōu)化

Android提供的多種位圖格式中,較高的是RGB_8888,也是系統默認的位圖格式,其他幾種都減少位圖通道,可以減少內存開(kāi)銷(xiāo),如一些局部圖片、小屏幕手機或者對圖片質(zhì)量要求不高的場(chǎng)景,均可以使用RGB_565,或者ARGB_ 4444 等圖像格式。

  • 圖片縮放:inSampleSize、inScaled、inDensity和inTargetDensity

  • 位圖內存重用:inBitmap的使用,可以結合LruCache實(shí)現。

  • 推薦開(kāi)源庫:picasso、Glide

15. Android 網(wǎng)絡(luò )通信框架Volley。

16. 對象池、線(xiàn)程池的合理使用。

17. 使用IntentService替代Service。

IntentService優(yōu)勢:新開(kāi)線(xiàn)程;順序處理Intent;執行完自動(dòng)退出。

18. 盡量不要因一兩個(gè)特性而使用大體積類(lèi)庫。

19. 對象不用時(shí)較好顯式置為Null可以減少GC開(kāi)銷(xiāo)。

20. 多了解并使用類(lèi)庫。

一些例子

1. 當處理字串的時(shí)候,盡量使用String.indexOf(),String.lastIndexOf()等特殊實(shí)現的方法。這些方法都是使用C/C++實(shí)現的,比起Java循環(huán)快 10 到 100 倍。

2. System.arraycopy方法在有JIT的Nexus One上,自行編碼的循環(huán)快 9 倍。

3. android.text.format包下的Formatter類(lèi),提供了IP地址轉換、文件大小轉換等方法;DateFormat類(lèi),提供了各種時(shí)間轉換,都是非常高效的方法。

4. TextUtils類(lèi),對于字符串處理Android為我們提供了一個(gè)簡(jiǎn)單實(shí)用的TextUtils類(lèi),如果處理比較簡(jiǎn)單的內容不用去思考正則表達式不妨試試這個(gè)在android.text.TextUtils的類(lèi)

5. 高性能MemoryFile類(lèi),對于I/O需要頻繁操作的,主要是和外部存儲相關(guān)的I/O操作,MemoryFile通過(guò)將 NAND或SD卡上的文件,分段映射到內存中進(jìn)行修改處理,這樣就用高速的RAM代替了ROM或SD卡,性能自然提高不少,對于A(yíng)ndroid手機而言同時(shí)還減少了電量消耗。該類(lèi)實(shí)現的功能不是很多,直接從Object上繼承,通過(guò)JNI的方式直接在C底層執行。

內存優(yōu)化工具

推薦內存分析工具:Memory Monitor  適用于A(yíng)ndroid Studio

推薦內存泄露分析工作:MAT 適用于eclipse、Android Studio

內存泄露監控工具:LeakCanary

更多資訊關(guān)注巨推傳媒:http://www.sixiiii-i.com/list-8/ 聯(lián)系電話(huà):400-606-5558 qq/微信:shijianyingxiao8