常用的Android性能優(yōu)化方法:
一、布局優(yōu)化:
1)盡量減少布局文件的層級。
層級少了,繪制的工作量也就少了,性能自然提高。
2)布局重用 <include標簽>
3)按需加載:使用ViewStub,它繼承自View,一種輕量級控件,本身不參與任何的布局和繪制過程。他的layout參數(shù)里添加一個替換的布局文件,當它通過setVisibility或者inflate方法加載后,它就會被內(nèi)部布局替換掉。
二、繪制優(yōu)化:
基于onDraw會被調(diào)用多次,該方法內(nèi)要避免兩類操作:
1)創(chuàng)建新的局部對象,導致大量垃圾對象的產(chǎn)生,從而導致頻繁的gc,降低程序的執(zhí)行效率。
2)不要做耗時操作,搶CPU時間片,造成繪制很卡不流暢。
三、內(nèi)存泄漏優(yōu)化:
1)靜態(tài)變量導致內(nèi)存泄漏 ? 比較明顯
2)單例模式導致的內(nèi)存泄漏?單例無法被垃圾回收,它持有的任何對象的引用都會導致該對象不會被gc。
3)屬性動畫導致內(nèi)存泄漏 ?無限循環(huán)動畫,在activity中播放,但是onDestroy時沒有停止的話,動畫會一直播放下去,view被動畫持有,activity又被view持有,導致activity無法被回收。
四、響應速度優(yōu)化:
1)避免在主線程做耗時操作 包括四大組件,因為四大組件都是運行在主線程的。
2)把一些創(chuàng)建大量對象等的初始化工作放在頁面回到前臺之后,而不應該放到創(chuàng)建的時候。
五、ListView的優(yōu)化:
1)使用convertView,走listView子View回收的一套:RecycleBin 機制
主要是維護了兩個數(shù)組,一個是mActiveViews,當前可見的view,一個是mScrapViews,當前不可見的view。當觸摸ListView并向上滑動時,ListView上部的一些OnScreen的View位置上移,并移除了ListView的屏幕范圍,此時這些OnScreen的View就變得不可見了,不可見的View叫做OffScreen的View,即這些View已經(jīng)不在屏幕可見范圍內(nèi)了,也可以叫做ScrapView,Scrap表示廢棄的意思,ScrapView的意思是這些OffScreen的View不再處于可以交互的Active狀態(tài)了。ListView會把那些ScrapView(即OffScreen的View)刪除,這樣就不用繪制這些本來就不可見的View了,同時,ListView會把這些刪除的ScrapView放入到RecycleBin中存起來,就像把暫時無用的資源放到回收站一樣。
當ListView的底部需要顯示新的View的時候,會從RecycleBin中取出一個ScrapView,將其作為convertView參數(shù)傳遞給Adapter的getView方法,從而達到View復用的目的,這樣就不必在Adapter的getView方法中執(zhí)行LayoutInflater.inflate()方法了。
RecycleBin中有兩個重要的View數(shù)組,分別是mActiveViews和mScrapViews。這兩個數(shù)組中所存儲的View都是用來復用的,只不過mActiveViews中存儲的是OnScreen的View,這些View很有可能被直接復用;而mScrapViews中存儲的是OffScreen的View,這些View主要是用來間接復用的。
2)使用ViewHolder避免重復地findViewById
3)快速滑動不適合做大量異步任務,結合滑動監(jiān)聽,等滑動結束之后加載當前顯示在屏幕范圍的內(nèi)容。
4)getView中避免做耗時操作,主要針對圖片:ImageLoader來處理(原理:三級緩存)
5)對于一個列表,如果刷新數(shù)據(jù)只是某一個item的數(shù)據(jù),可以使用局部刷新,在列表數(shù)據(jù)量比較大的情況下,節(jié)省不少性能開銷。
六、Bitmap優(yōu)化:
1)減少內(nèi)存開支:圖片過大,超過控件需要的大小的情況下,不要直接加載原圖,而是對圖片進行尺寸壓縮,方式是BitmapFactroy.Options 采樣,inSampleSize 轉成需要的尺寸的圖片。
2)減少流量開銷:對圖片進行質量壓縮,再上傳服務器。圖片有三種存在形式:硬盤上時是file,網(wǎng)絡傳輸時是stream,內(nèi)存中是stream或bitmap,所謂的質量壓縮,它其實只能實現(xiàn)對file的影響,你可以把一個file轉成bitmap再轉成file,或者直接將一個bitmap轉成file時,這個最終的file是被壓縮過的,但是中間的bitmap并沒有被壓縮。bitmap.compress(Bitmap.CompressFormat.PNG,100,bos);
七、線程優(yōu)化:
使用線程池。為什么要用線程池?
1、從“為每個任務分配一個線程”轉換到“在線程池中執(zhí)行任務”
2、通過重用現(xiàn)有的線程而不是創(chuàng)建新線程,可以處理多個請求在創(chuàng)建銷毀過程中產(chǎn)生的巨大開銷
3、當使用線程池時,在請求到來時間 ,不用等待系統(tǒng)重新創(chuàng)建新的線程,而是直接復用線程池中的線程,這樣可以提高響應性。
4、通過和適當調(diào)整線程池的大小 ,可以創(chuàng)建足夠多的線程以使處理器能夠保持忙碌狀態(tài),同時還可以防止過多線程相互競爭資源而使應用程序耗盡內(nèi)存或者失敗。
5、一個App里面所有的任務都放在線程池中執(zhí)行后,可以統(tǒng)一管理 ,當應用退出時,可以把程序中所有的線程統(tǒng)一關閉,避免了內(nèi)存和CPU的消耗。
6、如果這個任務是一個循環(huán)調(diào)度任務,你則必須在這個界面onDetach方法把這個任務給cancel掉,如果是一個普通任務則可cancel,可不cancel,但是最好cancel
7、整個APP的總開關會在應用退出的時間把整個線程池全部關閉。
八、一些性能優(yōu)化建議:
1)避免創(chuàng)建過多對象,造成頻繁的gc
2)不要過多使用枚舉,枚舉占用的空間比整型大很多
3)字符串的拼接使用StringBuffer、StringBuilder來替代直接使用String,因為使用String會創(chuàng)建多個String對象,參考第一條。
4)適當使用軟引用,(弱引用就不太推薦了)
5)使用內(nèi)存緩存和磁盤緩存。