面試時你被問到做過Android哪些優化時該回答什麼

一、佈局優化:

1)儘量減少佈局文件的層級。層級少了,繪製的工作量也就少了,性能自然提高。
2)佈局重用 include 標籤和 merge標籤
3)按需加載:使用ViewStub實現佈局懶加載

二、繪製優化:

基於onDraw會被調用多次,該方法內要避免兩類操作:

  • 創建新的局部對象,導致大量垃圾對象的產生,從而導致頻繁的gc,降低程序的執行效率。
  • 不要做耗時操作,搶CPU時間片,造成繪製很卡不流暢。

三、內存泄漏優化:

1)靜態變量導致內存泄漏
2)單例模式導致的內存泄漏 單例無法被垃圾回收,它持有的任何對象的引用都會導致該對象不會被gc。
3)屬性動畫導致內存泄漏 無限循環動畫,在activity中播放,但是onDestroy時沒有停止的話,動畫會一直播放下去,view被動畫持有,activity又被view持有,導致activity無法被回收。

四、響應速度優化:

1)避免在主線程做耗時操作 包括四大組件,因爲四大組件都是運行在主線程的。
2)把一些創建大量對象等的初始化工作放在頁面回到前臺之後,而不應該放到創建的時候。

五、ListView的優化:

1)使用convertView,走listView子View回收的一套:

RecycleBin 機制主要是維護了兩個數組,一個是mActiveViews,當前可見的view,一個是mScrapViews,當前不可見的view。

當觸摸ListView並向上滑動時,ListView上部的一些OnScreen的View位置上移,並移除了ListView的屏幕範圍,此時這些OnScreen的View就變得不可見了,不可見的View叫做OffScreen的View,即這些View已經不在屏幕可見範圍內了,也可以叫做ScrapView,Scrap表示廢棄的意思,ScrapView的意思是這些OffScreen的View不再處於可以交互的Active狀態了。

ListView會把那些ScrapView(即OffScreen的View)刪除,這樣就不用繪製這些本來就不可見的View了,同時,ListView會把這些刪除的ScrapView放入到RecycleBin中存起來,就像把暫時無用的資源放到回收站一樣。

當ListView的底部需要顯示新的View的時候,會從RecycleBin中取出一個ScrapView,將其作爲convertView參數傳遞給Adapter的getView方法,從而達到View複用的目的,這樣就不必在Adapter的getView方法中執行LayoutInflater.inflate()方法了。

RecycleBin中有兩個重要的View數組,分別是mActiveViews和mScrapViews。這兩個數組中所存儲的View都是用來複用的,只不過mActiveViews中存儲的是OnScreen的View,這些View很有可能被直接複用;而mScrapViews中存儲的是OffScreen的View,這些View主要是用來間接複用的。

2)使用ViewHolder避免重複地findViewById

3)快速滑動不適合做大量異步任務,結合滑動監聽,等滑動結束之後加載當前顯示在屏幕範圍的內容。

4)getView中避免做耗時操作,主要針對圖片:ImageLoader來處理(原理:三級緩存)

5)對於一個列表,如果刷新數據只是某一個item的數據,可以使用局部刷新,在列表數據量比較大的情況下,節省不少性能開銷。

6)最重要的一點:使用 RecyclerView 代替 Listview。

六、Bitmap優化:

1)減少內存開支:圖片過大,超過控件需要的大小的情況下,不要直接加載原圖,而是對圖片進行尺寸壓縮,方式是BitmapFactroy.Options 採樣,inSampleSize 轉成需要的尺寸的圖片。

2)減少流量開銷:對圖片進行質量壓縮,再上傳服務器。圖片有三種存在形式:硬盤上時是file,網絡傳輸時是stream,內存中是stream或bitmap,所謂的質量壓縮,它其實只能實現對file的影響,你可以把一個file轉成bitmap再轉成file,或者直接將一個bitmap轉成file時,這個最終的file是被壓縮過的,但是中間的bitmap並沒有被壓縮。bitmap.compress(Bitmap.CompressFormat.PNG,100,bos);

七、線程優化:

使用線程池。爲什麼要用線程池?

1、從“爲每個任務分配一個線程”轉換到“在線程池中執行任務”。

2、通過重用現有的線程而不是創建新線程,可以處理多個請求在創建銷燬過程中產生的巨大開銷

3、當使用線程池時,在請求到來時間 ,不用等待系統重新創建新的線程,而是直接複用線程池中的線程,這樣可以提高響應性。

4、通過和適當調整線程池的大小 ,可以創建足夠多的線程以使處理器能夠保持忙碌狀態,同時還可以防止過多線程相互競爭資源而使應用程序耗盡內存或者失敗。

5、一個App裏面所有的任務都放在線程池中執行後,可以統一管理 ,當應用退出時,可以把程序中所有的線程統一關閉,避免了內存和CPU的消耗。

6、如果這個任務是一個循環調度任務,你則必須在這個界面onDetach方法把這個任務給cancel掉,如果是一個普通任務則可cancel,可不cancel,但是最好cancel。

7、整個APP的總開關會在應用退出的時間把整個線程池全部關閉。

八、一些性能優化建議:

1)避免創建過多對象,造成頻繁的gc。
2)不要過多使用枚舉,枚舉佔用的空間比整型大很多。
3)字符串的拼接使用StringBuffer、StringBuilder來替代直接使用String,因爲使用String會創建多個String對象,參考第一條。
4)適當使用軟引用,(弱引用就不太推薦了)
5)使用內存緩存和磁盤緩存。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章