後期我會面試50家互聯網公司,不斷總結完善和思考,寫出一本完美的安卓面試書籍,大家支持我嗎?
目錄
1、內存優化
2、ui優化
3、網絡優化
4、啓動優化
1、內存優化
1.1、解決所有的內存泄漏
1.1.1、內存泄漏:
堆上分配的對象已經不會再使用,但是GC收集器無法對其進行回收,此對象被強應用所引用 。
1.1.2、GC收集器原理:
可達性算法:從GCRoot對象爲起點,向下搜索,可到達的對象是稱爲GC可達,GC收集器不會回收,不可到達的對象稱爲不GC不可達,是GC收集器回收的對象。
GCRoot對象:
(1)、虛擬機棧(棧幀找那個的局部變量表)中的對象;
(2)、方法區中類靜態變量引用的對象;
(3)、方法區中常量引用的對象。
1.1.3、常見的內存泄漏實例
(1)、單例造成的內存泄漏
單例類的實例是靜態的,如果需要其構造方法需要傳遞一個context,如果傳入的是 Activity 的 Context,當傳入 Activity 就會造成泄漏了。
解決方法:this.context = context.getApplicationContext();// 使用Application 的context。
(2)、內部類造成的內存泄漏
在Activity中有一個內部類,如果創建了這個內部類的靜態對象,Activity關閉的時候,由於內部類會持有外部類的引用,內部類靜態對象會持有外部類Activity的引用,導致Activity發生內存泄漏。
解決方法:將該內部類設爲靜態內部類,如果該內部類需要持有外部類的引用,則使用軟引用/弱引用,在使用外部類的引用之前需進行空判斷。
(3)、異步線程造成的內存泄漏
在Activity中有一個開啓一個線程執行一個runnable,這個runnable是內部類就會持有外部類Activity的引用,如果線程的生命週期比Activity的生命週期長,就不會導致Activity內存泄漏。
解決方法:同上
(4)、Handler 造成的內存泄漏
在Activity中聲明一個內部類handler,當使用這個handler發送一個延遲消息時,此消息執行前,Activity關閉會造成內存泄漏。
解決方法:同上
(5)資源未關閉造成內存泄漏
對於使用了BraodcastReceiver,ContentObserver,File,遊標 Cursor,Stream,Bitmap等資源的使用,應該在Activity銷燬時及時關閉或者註銷,否則這些資源將不會被回收,造成內存泄漏。
1.1.4、內存泄漏檢測方案
LeakCanary原理:
LeakCanary在一個Fragment或者Activity onDestory的時候,創建一個弱引用
KeyedWeakReference
到要被監控的對象。然後在後臺線程檢查引用是否被清除,如果沒有,調用GC。
如果引用還是未被清除,把 heap 內存 dump 到 APP 對應的文件系統中的一個
.hprof
文件中。在另外一個進程中的
HeapAnalyzerService
有一個HeapAnalyzer
使用HAHA 解析這個文件。得益於唯一的 reference key,
HeapAnalyzer
找到KeyedWeakReference
,定位內存泄露。HeapAnalyzer
計算 到 GC roots 的最短強引用路徑,並確定是否是泄露。如果是的話,建立導致泄露的引用鏈。
1.2、避免內存抖動
內存抖動代表頻繁GC,會佔用程序執行時間,造成頁面卡頓等性能問題。
1.2.1、避免內存抖動的方式:
(1)、避免在onDraw中創建Paint、Bitmap對象等;
(2)、避免在循環中創建臨時對象;
(3)、避免在scrollListener中創建對象。
1.3、內存抖動檢測方法
(1)、使用Android profiler 進行觀察,如果發下內存劇增劇減則是GC時間,可查看GC時間段的內存,找出重複創建的大量對象,進行優化(例子:在recycleview中獲取距離屏幕的距離時,創建大量對象)。
1.3、圖片優化
(1)、網絡圖片:使用網絡裁剪服務,獲取適當的圖片加載。
(2)、本地圖片:使用Tinypng深度壓縮,必要時進行裁剪。
(3)、使用web格式代替png、jpeg格式。
(4)、使用Fresco對圖片進行管理。
1.3.1、fresco對內存的管理:
(1)、在5.0以下系統,Bitmap緩存位於ashmem,這樣Bitmap對象的創建和釋放將不會引發GC,更少的GC會使你的APP運行得更加流暢。5.0及其以上系統,相比之下,內存管理有了很大改進,所以Bitmap緩存直接位於Java的heap上。
(2)、當應用在後臺運行時,該內存會被清空。
1.4、使用優化的數據結構
2、ui優化
2.1、分析佈局,減少佈局嵌套或者替換消耗性能少的佈局
2.2、使用include+merge減少佈局層級
2.3、使用viewstub提供按需加載
3、網絡優化
3.1、網絡速度:
正常一條網絡請求需要經過的流程是這樣:
(1)、DNS 解析,請求DNS服務器,獲取域名對應的 IP 地址;
(2)、與服務端建立連接,包括 tcp 三次握手,安全協議同步流程;
(3)、連接建立完成,發送和接收數據,解碼數據。
這裏有明顯的三個優化點:
3.1、IP直連或者HTTPDNS;
3.2、開啓 keep-alive進行連接複用;
3.3、減少請求和返回數據的大小;
(1)、請求和返回數據做Gzip壓縮;
(2)、精簡數據格式;
(3)、按需加載圖片(圖片裁剪,也可按網絡狀態返回不同分辨率的圖片);