android啟動優(yōu)化
從三個方面進行優(yōu)化「減少阻塞」「延遲執(zhí)行」「優(yōu)化效率」
1、減少Application阻塞,避免在onCreate()中執(zhí)行耗時操作(如 IO、網(wǎng)絡(luò)請求、復雜計算)
2、第三方庫(如埋點、統(tǒng)計、推送)按需初始化,必需的庫(如網(wǎng)絡(luò)框架)用異步初始化(子線程執(zhí)行)
3、優(yōu)化布局繪制(減少首次繪制耗時),減少布局層級:用ConstraintLayout替代嵌套的LinearLayout/RelativeLayout(扁平化層級,減少 measure/layout 時間)。
4、啟動頁(SplashActivity)僅負責顯示 Logo / 廣告,不做復雜初始化(將邏輯移到Application或主 Activity 的子線程)。(注意)根據(jù)產(chǎn)品需求來定,看閃屏頁廣告是否停留固定的時長,啟動頁停留時間 = 實際初始化時間,而非固定延遲(如Thread.sleep(2000)會強制拉長啟動時間)
解決啟動時白屏 / 黑屏:
在啟動頁主題中設(shè)置windowBackground為 Logo 或背景圖
android事件分發(fā)
事件分發(fā)的邏輯通過三個關(guān)鍵方法實現(xiàn),不同組件對方法的實現(xiàn)不同:(如圖1)

事件從 Activity 出發(fā),自上而下傳遞給子 View;若子 View 不處理,事件會自下而上回溯,由父容器或 Activity 處理。
自己的理解:事件分發(fā)機制與 OkHttp 的攔截器鏈條在執(zhí)行邏輯上確實有高度相似性,它們本質(zhì)上都屬于責任鏈模式
事件分發(fā)的核心流程是 **“自上而下傳遞,自下而上回溯”**,形成一條處理鏈:
1.起點是Activity,然后傳遞給頂層ViewGroup,再傳遞給子ViewGroup,最終到達View(鏈條的各個節(jié)點)。
2.每個節(jié)點(Activity/ViewGroup/View)都有兩個選擇:處理事件(返回true,終止傳遞)
或不處理(返回false,讓事件繼續(xù)傳遞給下一個節(jié)點)。
3.若所有子節(jié)點都不處理,事件會 “回溯” 給父節(jié)點,直到被處理或終止。
OkHttp 的網(wǎng)絡(luò)請求核心是攔截器鏈(Interceptor Chain),其執(zhí)行邏輯是 **“請求沿鏈傳遞,響應反向回溯”**
1.起點是用戶發(fā)起的Request,依次經(jīng)過RetryAndFollowUpInterceptor(重試與重定向)、BridgeInterceptor(補全請求頭)、
CacheInterceptor(緩存處理) 、ConnectInterceptor(建立連接)等攔截器(鏈條的各個節(jié)點)。
2.每個攔截器有兩個選擇:處理部分邏輯后傳遞給下一個攔截器(通過chain.proceed(request)觸發(fā)下一個節(jié)點),
或直接返回響應(終止傳遞)。
3.最終請求到達CallServerInterceptor(與服務器交互),得到Response后,再反向經(jīng)過所有攔截器(如CacheInterceptor緩存響應),
最終返回給用戶。
RecyclerView 四級緩存

一級:mAttachedScrap(附著的廢棄視圖)還 “掛” 在 RecyclerView 上的臨時廢棄ViewHolder(未完全脫離)。
仍附著在 RecyclerView 上,但暫時不在 “當前可見區(qū)域” 的ViewHolder。
舉例: 滾動時,某個 Item 從屏幕中間慢慢滑到邊緣(部分可見或剛完全不可見,但還沒被 RecyclerView “剝離”)。二級:mCachedViews(緩存視圖)剛完全滑出屏幕、保留數(shù)據(jù)的ViewHolder(最近被移除)。
完全滑出屏幕,且最近被移除的ViewHolder 。
保留完整數(shù)據(jù)(比如 Item 的文本、圖片等),復用時有嚴格的position匹配(只有新 Item 的位置和緩存中ViewHolder的原位置一致時,才會直接復用,無需onBind)
三級:ViewCacheExtension(擴展緩存)開發(fā)者自定義緩存的特殊ViewHolder(按需實現(xiàn))。
完全由開發(fā)者控制緩存哪些ViewHolder、如何復用。
自定義緩存邏輯(比如按id而非position匹配),適合業(yè)務中高頻復用的特殊類型 Item四級:RecyclerPool(回收池)按類型分類、已清數(shù)據(jù)的通用ViewHolder(緩存池)。
按ViewType分類存儲、已清除數(shù)據(jù)的ViewHolder。
不關(guān)心position,只按ViewType分組(比如文本 Item 和圖片 Item 分開緩存)。
復用前必須重新綁定數(shù)據(jù)(會觸發(fā)onBindViewHolder),因為數(shù)據(jù)已被清除。
使用過程:
二級緩存:默認最多緩存 2 個(可通過setItemViewCacheSize修改數(shù)量)。
四級緩存:支持跨 RecyclerView 共享(如 ViewPager 中的多個 RecyclerView 可共享同一個RecyclerPool),
減少不同列表間的ViewHolder創(chuàng)建開銷。
減少apk體積
從四個方面進行優(yōu)化「刪冗余」「壓資源」「優(yōu)代碼」「智分包」
刪冗余:移除未使用的資源
壓資源:圖片用矢量圖替代,用webp替代png/jpg
優(yōu)代碼:開啟混淆,用輕量庫(如okhttp替代volley)
智分包:架構(gòu)適配,v7a,v8a單獨打包
//混淆
minifyEnabled true
//Zipalign優(yōu)化
zipAlignEnabled true
// 移除無用的resource文件
shrinkResources true
內(nèi)存優(yōu)化
1、好用的內(nèi)存檢查工具
談到內(nèi)存優(yōu)化,一些好用的內(nèi)存檢測工具有,LeakCanary庫(自動檢測內(nèi)存泄露),android studio自帶的profiler抓取內(nèi)存快照,分析內(nèi)存占比(比如發(fā)現(xiàn)“大圖片未壓縮導致bitmap占用過高”),allocation tracker(跟蹤對象創(chuàng)建軌跡,定位頻繁創(chuàng)建的臨時對象,比如循環(huán)中重復創(chuàng)建Paint對象)。
2、內(nèi)存占用高,內(nèi)存泄漏,內(nèi)存抖動三方面來說
- 內(nèi)存泄露:靜態(tài)引用、匿名內(nèi)部類、資源未關(guān)閉
- 大內(nèi)存對象優(yōu)化:bitmap優(yōu)化(加載時壓縮,在獲取圖片的原始寬高信息通過設(shè)inJustDecodeBounds屬性,在不加載完整圖片到內(nèi)存的情況下,獲取圖片的原始寬高信息,用RGB_565替代ARGB_8888,內(nèi)存減少一半,設(shè)置inSampleSize按需縮放,比如Imageview是200x200,就加載200x200的bitmap,而非原圖),還有復用內(nèi)存LruCache緩存常用bitmap(比如列表圖片緩存,超出容量自動回收)
- 內(nèi)存抖動:短時間大量創(chuàng)建/回收臨時對象,導致GC頻繁觸發(fā)(卡頓)
1、循環(huán)中不重復創(chuàng)建String(用StringBuilder拼接)、自定義view,ondraw方法中,Paint、Rect改為全局復用
2、針對int類型的集合,改為安卓封裝的集合,SparseIntArray
3、頁面/組件優(yōu)化(按需加載)
- 延遲加載 viewpager用懶加載(僅加載當前頁和相鄰也,而非全部加載),列表用Recyclerview復用itemview而非自定義列表,避免重復創(chuàng)建view
HashMap理解
定位+沖突+擴容 (數(shù)組+鏈表+紅黑樹)
定位:tab[(n - 1) & hash]
沖突:hash一樣equals不一樣導致hash沖突,6個以下鏈表,6個以上紅黑樹
擴容:2倍,位運算