App啟動優(yōu)化,一種較優(yōu)秀的方案


項目重構(gòu)App的啟動屹徘,之前的處理是使用SplashActivity作為過渡頁走趋,然后將Application中的第三方SDK放到IntentService中加載,啟動過程中的一些耗時操作也都去掉了噪伊,奈何MainActivity中的業(yè)務(wù)邏輯還是太過復(fù)雜簿煌,啟動仍然比較漫長氮唯。研究了一下淘寶項目的啟動處理,總結(jié)出一種非常優(yōu)化的App啟動方案姨伟。

傳統(tǒng)的啟動處理

市面上大部分的App啟動處理如出一轍惩琉,基本都是先進(jìn)入SplashActivity,然后Handler延時后跳轉(zhuǎn)到MainActivity夺荒。這樣做的好處是SplashActivity作為過渡頁更加輕量瞒渠,啟動到顯示界面的時間更短,給用戶較好的體驗技扼,而且SplashActivity中也可以提前做一些數(shù)據(jù)處理在孝,減輕MainActivity的壓力。但是加入SplashActivity過渡頁也有一些缺點淮摔,比如要多繪制一個頁面,要使用Intent傳遞數(shù)據(jù)始赎,不能減輕MainActivity頁面的繪制壓力和一些數(shù)據(jù)加載和橙。


傳統(tǒng)的啟動處理

除此之外,Application的處理也是一個很重要的點造垛,因為App啟動是先走Application的onCreate方法的魔招,如果onCreate中加載SDK的時間過于漫長,就會導(dǎo)致App啟動后顯示一段時間白屏頁才會進(jìn)入SplashActivity五辽,當(dāng)然也可以使用windowBackGround屬性避免白屏办斑,但是時間長了總是會影響用戶體驗的。所以Application中一般都是采用IntentService來加載SDK的杆逗。

為了解決App啟動慢和SplashActivity過渡啟動的缺點乡翅,個人去研究了一下淘寶的啟動,發(fā)現(xiàn)第一次啟動耗時大概3秒蠕蚜,然后退出去悔橄,再進(jìn)入時就不會顯示Splash癣疟,直接進(jìn)入主頁讀取緩存顯示頁面。我猜測淘寶的啟動肯定是根據(jù)應(yīng)用的進(jìn)程是否存活邪蛔,如果存活就直接進(jìn)入MainActivity店溢,否則顯示Splash,而且淘寶的Splash加載很快荣回,MainActivity的加載也很快戈咳,所以淘寶應(yīng)該是采用了Splash綁定在Mainactivity上的方式著蛙,即SplashFragment+StubView的方式啟動App。

優(yōu)化后的Splash

傳統(tǒng)的App啟動方式不足以滿足現(xiàn)在用戶的體驗猎唁,用戶需要的是加載更快顷蟆,性能更優(yōu)的體驗帐偎,所以這里采用SplashFragment+StubView的方式去實現(xiàn)App的快速啟動。


優(yōu)化后的Splash

跟傳統(tǒng)啟動方式最大的不同是,優(yōu)化后的啟動會直接進(jìn)入MainActivity漫贞,然后在MainActivity控制Splash的顯示隱藏,這樣在填充Splash的時候還以為直接加載MainActivity的數(shù)據(jù)摇肌,當(dāng)窗體填充完畢之后仪际,就可以繪制MainActivity的布局树碱,然后移除Splash,展示頁面框舔,這種方式很好的體現(xiàn)了異步的操作,使得填充和加載分離樱溉,啟動的速度更快纬凤。

既然知道了這種實現(xiàn)方式,那具體代碼是如何編寫的呢挖帘,接下來看一下如何實現(xiàn)拇舀。

1. 填充SplashFragment

在MainActivity的onCreate方法中骄崩,首先薄辅,需要做的就是填充Splash并顯示,顯示的內(nèi)容就可以在SplashFragment中編輯。

    log.d(TAG, "==========填充SplashFragment==========");
    // 1.初始化SplashFragment源请,填充Splash
    final SplashFragment splashFragment = new SplashFragment();
    getFragmentManager().beginTransaction().replace(R.id.container,splashFragment).commitAllowingStateLoss();

2. 窗體部署完畢彻况,填充主頁布局

當(dāng)整個頁面最底層DecorView填充完畢之后纽甘,就可以開始去填充MainActivity的布局了,并且使用Handler發(fā)送延時消息决瞳,2秒后移除Splash皮胡。當(dāng)然移除Splash也可以直接在數(shù)據(jù)加載完畢顯示頁面之前移除掉赏迟。

    getWindow().getDecorView().post(new Runnable() {
        @Override
        public void run() {
            // 填充布局
            viewStub.inflate();
            // 初始化布局
            initView();
            // 2秒后移除Splash
            mHandler.postDelayed(new DelayRunnable(MainActivity.this, splashFragment), 2000);
        }
    });

3. 加載MainActivity數(shù)據(jù)

其實加載數(shù)據(jù)會在第二步之前執(zhí)行,因為第二步是異步操作泻仙,并且加載數(shù)據(jù)是耗時操作量没,所以需要更早執(zhí)行允蜈,不要放在第二步里去執(zhí)行饶套,這里在測試的時候有可能數(shù)據(jù)先加載完畢,布局才繪制完怠李,調(diào)用控件就會有空指針問題蛤克,但是實際開發(fā)中肯定不會出現(xiàn)這種情況的构挤,MainActivity中的數(shù)據(jù)加載肯定很耗時筋现。

Application的優(yōu)化

Application是應(yīng)用的核心樞紐,應(yīng)用啟動時會先走Application的onCreate方法去初始化一些全局?jǐn)?shù)據(jù)一膨,比如SDK等等豹绪。但是當(dāng)全局?jǐn)?shù)據(jù)很多時,App的啟動就會變得緩慢瞒津,因為初始化是同步加載的括尸,所以要想加快啟動姻氨,就需要將延時操作放到后臺去處理。

Android里有一個Service前联,正好可以做延時處理的操作似嗤,這個Service就是IntentService。關(guān)于IntentService乘粒,不了解的看這里灯萍。
IntentService 示例與詳解
IntentService文檔

接下來旦棉,看一下如何實現(xiàn)药薯。

  • 自定義InitializeService繼承IntentService童本,實現(xiàn)構(gòu)造和方法onHandleIntent

  • 在Application的onCreate方法中啟動初始化服務(wù)

     // 啟動服務(wù)去做耗時操作
     InitializeService.start(this);

     public static void start(Context context) {
           Intent intent = new Intent(context, InitializeService.class);
            intent.setAction(ACTION_APP_LAUNCHER);
            context.startService(intent);
     }
  • 在onHandleIntent方法中判斷Intent穷娱,然后去初始化SDK
     @Override
      protected void onHandleIntent(@Nullable Intent intent) {
          if (intent != null) {
                final String action = intent.getAction();
                if (ACTION_APP_LAUNCHER.equals(action)) {
                    performInit();
                }
          }
      }
    
    
        /**
         * 啟動初始化耗時操作
         */
        private void performInit() {
            // 模擬延時加載
            SystemClock.sleep(2000);
            Log.d(TAG, "==========初始化第三方SDK結(jié)束==========");
         }

注意:

  • 在清單文件中配置Application和Service
  • 并不是所有的SDK都能放到Service中去初始化的,在MainActivity中用到的還是需要提前初始化

Demo地址


歡迎大家訪問我的簡書梯刚,博客GitHub亡资。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锥腻,一起剝皮案震驚了整個濱河市瘦黑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌匹摇,老刑警劉巖廊勃,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件经窖,死亡現(xiàn)場離奇詭異冰悠,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)棉钧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門的诵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來佑钾,“玉大人西疤,你說我怎么就攤上這事⌒萑埽” “怎么了代赁?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兽掰。 經(jīng)常有香客問我芭碍,道長,這世上最難降的妖魔是什么孽尽? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任窖壕,我火速辦了婚禮,結(jié)果婚禮上杉女,老公的妹妹穿的比我還像新娘瞻讽。我一直安慰自己,他們只是感情好熏挎,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般楣嘁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天杨帽,我揣著相機(jī)與錄音,去河邊找鬼僚饭。 笑死偿乖,一個胖子當(dāng)著我的面吹牛外邓,可吹牛的內(nèi)容都是我干的侦啸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼私恬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起涮瞻,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤艇抠,失蹤者是張志新(化名)和其女友劉穎絮重,沒想到半個月后殴瘦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姨蟋,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡绑咱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年薄榛,在試婚紗的時候發(fā)現(xiàn)自己被綠了硬猫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡终蒂,死狀恐怖睁蕾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情藏杖,我是刑警寧澤敢辩,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布戚长,位于F島的核電站,受9級特大地震影響柑司,放射性物質(zhì)發(fā)生泄漏咒程。R本人自食惡果不足惜奶段,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一悠垛、第九天 我趴在偏房一處隱蔽的房頂上張望派草。 院中可真熱鬧缴罗,春花似錦、人聲如沸祭埂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛆橡。三九已至舌界,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泰演,已是汗流浹背呻拌。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留睦焕,地道東北人藐握。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓愿阐,卻偏偏與公主長得像袜蚕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子锰扶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,524評論 25 707
  • 轉(zhuǎn)自 1. 什么是Activity? 四大組件之一,一般的,一個用戶交互界面對應(yīng)一個activity setCon...
    joe1632閱讀 1,388評論 0 7
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理本谜,服務(wù)發(fā)現(xiàn)初家,斷路器,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 谷歌官方文檔:https://developer.android.com/topic/performance/la...
    路Promenade閱讀 2,360評論 18 15
  • 行走在無邊無際的原野 輕風(fēng)佛面 金色麥浪搖曳著它動人的身軀 小溪潺潺 魚兒輕搖著它柔軟的腰肢 歌聲陣陣 老農(nóng)哼唱著...
    月夜醉聽風(fēng)閱讀 253評論 1 2