Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android資訊 >> Android端應用秒開優化體驗

Android端應用秒開優化體驗

編輯: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的創建

如圖:

launch

對任務這樣分級後,測了一下,應用的啟動即使在低端機上,也能秒開:

分級帶來的問題

正常啟動過程那肯定是沒問題的,不過有這麼幾種場景:

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);
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved