編輯:Android資訊
最近部門內拋出了一個問題,應用啟動很慢、卡圖標?主要表現在中低端機型中。究其這個問題,由於對性能優化比較感興趣,借了個低端機和一個中端機來一看究竟,對同一應用分別測了下它在中低端機的啟動時間,下面為啟動耗時情況:
啟動了三次,基本都在4s左右。
究其原因,主要因素是任務在界面繪制前過於集中化。
應用啟動過程從用戶點擊launcher圖標到看到第一幀這個過程中,主要會經過以下這些過程:
main()->Application:attachBaseContext()->onCreate()->Activity:onCreate()->onStart()->onPostCreate()->onResume()->onPostResume()
而一般我們的初始化任務主要都會集中化在Application:onCreate()方法中,這就使得初始化任務在第一幀繪制之前得完成,這就造成了卡圖標、應用啟動慢。那麼把任務打散呢?分散在LaunchActivity中去分段初始化?還是不行的,因為界面開始繪制是在onResume()方法開始後才開始繪制,所以,得從Activity的創建過程找辦法。
main->Activity創建的這個過程會經過一系列framework層的操作,這些操作都是系統自動執行的,不易進行優化,不過可以在Activity創建這個過程前後來找一些蛛絲馬跡,因為Activity的創建都會輾轉到ActivityThread:performLaunchActivity()這個方法中,在這個方法中可以知道這麼幾件事:
1、先通過Instrumentation:newActivity()來創建一個Activity實例
2、再判斷Application實例是否已創建,已創建則直接返回,否則調用
Instrumentation:newApplication()來創建Application實例,在這個過程中會依次執行attachBaseContext()和onCreate()方法
3、之後Activity:attach()方法會創建一個PhoneWindow對象,它就是界面,它有一個DecorView,調用setContentView()時會給配置DecorView,其中就會設置一個背景:
我們的View也是add進DecorView中顯示,它作為RootView肯定是最先顯示,所以可以給它設置個默認背景
4、最後依次調用Activity的onCreate、onStart等方法
1、任務分級
2、任務並行
3、界面預顯示
對於任務集中初始化化、耗時初始化原因導致應用在中低端機啟動過慢,而Activity界面繪制的時機導致簡單的將任務分給Activity初始化也不起作用,我們必須找一個切入點
界面的創建和界面的繪制,這兩個過程第一個是Application的attachBaseConte和onCreate這兩個方法影響的,第二個則是Application創建一直到界面繪制
所以,可以對任務進行分級的臨界點可以這樣分:
1、CoreSDK——Application的創建
2、HighPrioritySDK——Activity的創建
3、LowPrioritySDK——Activity界面完成繪制
4、AsyncSDK——Activity的創建
如圖:
對任務這樣分級後,測了一下,應用的啟動即使在低端機上,也能秒開:
正常啟動過程那肯定是沒問題的,不過有這麼幾種場景:
1、App切回後台,內存不足導致Application被回收,從最近任務列表中恢復界面時Application需重新創建
2、應用沒掛起時,Push推送需從Notification跳入應用內某界面
3、應用沒掛起時,浏覽器外鏈需跳入應用內某界面
這些Case可能導致的問題是被跳入的界面使用到了未初始化的SDK,可能導致Crash或者數據異常,所以目標頁面啟動前必須確保SDK已經初始化,這個過程的原因是沒有喚起啟動頁來初始化SDK,可以通過hook newActivity解決。
public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { if (InitializeOptimizer.isApplicationCreated() && (InitializeUtil.isOuterChainIntent(intent) || InitializeUtil.isNotificationIntent(intent)) && (!InitializeOptimizer.isHighSDKInitialized() || !InitializeOptimizer.isLowSDKInitialized() || !InitializeOptimizer.isAsyncSDKInitialized())) { InitializeOptimizer.setApplicationCreated(false); intent.addCategory(InitializeUtil.INITIALIZE_CATEGORY); return (Activity) cl.loadClass(InitializeOptimizer.getLaunchClassName()).newInstance(); } InitializeOptimizer.setApplicationCreated(false); return super.newActivity(cl, className, intent); }
一、OOM問題出現的場景和原因 一個好的app總少不了精美的圖片,所以Android開發中圖片的加載總是避免不了的,而在加載圖片過程中,如果處理不當則會出現OOM
2014 年,隨著 Google 推出了全新的設計語言 Material Design,還迎來了新的 Android 支持庫 v7,其中就包含了 Material
所謂MVP(Model-View-Presenter)模式。是將APP的結構分為三層: view – UI顯示層 view 層主要負責: 提供UI交
Fragment是Android中的重要組件,在Android 3.0的時候添加進來。 關於Fragment的生命周期,我相信了解過的開發人員都應該把以下方法脫口