App 冷啟動與熱啟動及啟動白屏優化
介紹一下 app 冷啟動和熱啟動方式來實現 app 秒開的效果。那麼,先來看看什麼叫冷啟動和熱啟動。
冷啟動:指 app 被後臺殺死後,在這個狀態開啟 app,這種啟動方式叫做冷啟動。
熱啟動:指 app 沒有被後臺殺死,仍然在後臺執行,通常我們再次去開啟這個 app,這種啟動方式叫熱啟動。
那麼,何為閃屏頁呢?這個大家一般都知道,我們 app 也非常常見的。比如微信、QQ 等等應用,你將這些應用清除掉它們的後臺執行的情況下,再去開啟。這時候會出現一個閃屏頁,類似我們的背景頁。這個頁面停留的時間非常短,一般不會超過 3秒,太久了就會使使用者感覺這個 app 好卡的樣子。
然後,我們看新建的一個專案,不做任何操作執行時會發現它在啟動之時會有一個白屏的時間。那麼,大部分 app 的解決方式就是我上面提到的閃屏頁來替換白屏頁。其實,也就是替換預設的 activity 的 theme。我們看看白屏的效果(其實在我點下的瞬間,已經是白屏了。模擬器也許遮蔽了,在手機上非常直觀)
白屏效果
為什麼替換?這就是提升我們的使用者體驗了,可以發現我們白屏頁顯得非常的難看,而且使用者可能會誤以為這是app卡的結果造成的。如果我們換成了閃屏頁,不僅可以為app新增屬於自己的臉面,也可以造成一種app秒開的假象。使用者發現app已經被打開了,為何遲遲不進去,那可能是覺得手機不夠給力啊,哈哈。
實現步驟
我們提到秒開app,不管它是一種假象也罷,既然市面上大部分的app都是這麼處理的,不妨我們也學習一下。
一、設定 style 主題
首先,我們為閃屏頁設定它的style,通常它是隱藏標題欄、隱藏狀態列、全屏的,然後用一張突顯app主題的背景圖片來填充整個螢幕。那麼,我們這樣設定它:
<!--閃屏頁--> <style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:windowBackground">@drawable/bg_splash_theme_leader</item> <item name="android:windowNoTitle">true</item> <item name="android:windowFullscreen">true</item> </style> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <bitmap android:gravity="fill" android:src="@drawable/splash" /> </item> </layer-list>
二、繫結到 Activity 上
然後,將這一主題運用到我們需要的activity上,比如我的SplashActivity:
<activity android:name=".SplashActivity" android:launchMode="singleTask" android:screenOrientation="portrait" android:theme="@style/SplashTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
最後,執行專案,你就會體會到什麼叫做冷啟動秒開應用了。我們先前的白屏頁面,最終變成了一張自己的圖片,即顯得美觀,又達到了秒開的目的,真是一舉兩得!
分析
注意:我們的SplashActivity不做任何初始化和設定佈局,在onCreate中直接開啟我們的MainActivity就行了。否則,在SplashActivity中停留過多的時間,就會出現卡在閃屏頁許久才進入,我們的秒開也就變了味。
再說說我們的熱啟動實現方式,通常我們按下back鍵時,activity的生命週期會執行onStop,onDestory ——> onCreate。造成我們試圖被銷燬了又得重新建立。但是,我們按下home鍵卻是不一樣的,activity的生命週期會執行onStop ——>onReStart,所以熱啟動就是以back鍵替換成了home鍵,其實app是被置到了後臺,所以當你再次點選開啟app時,它會馬上的啟動。
但是,這類app通常是用於後臺處理比較重要的,比如QQ後臺接收資訊,音樂播放器後臺播放,通常都是遮蔽了back鍵,或者會有一個back鍵防誤觸操作。當然,這就得我們自己的app的自身需求了,通常做法就是將back鍵改為home鍵操作。
/** * App 熱啟動方式,實現應用程式秒開效果 */ @Override public void onBackPressed() { //直接返回桌面 ( Activity只執行onStop ) if (isStartHome()) { Intent intent = new Intent("android.intent.action.MAIN"); intent.addCategory("android.intent.category.HOME"); startActivity(intent); } else { super.onBackPressed();//( Activity將執行onDestory ) } }
一種優化啟動的思路
這是我很久之前看到的一種思路,既然說到閃屏頁,那就一併說明。它是利用EventBus,在application的建立時期不載入各種配置和各種庫,而是先顯示閃屏頁。在閃屏頁中,利用EventBus開啟各種配置和庫的載入(application中進行),等到這些庫載入完畢後,再次利用EventBus傳送事件進入主介面。
思路就是利用閃屏頁的時間用於載入各種配置和庫,而不是在application建立時就載入。我們看一下程式碼的實現方式
/** * @Created by xww. * @Creation time 2018/8/25. */ public abstract class WeatherAppclication extends Application { @Override public void onCreate() { super.onCreate(); //在此,先不載入庫 EventBus.getDefault().register(this); } @Subscribe public void init(String event) { //在這裡初始化一坨一坨的庫 if ("initConfigurations".equals(event)) { Weather.init(this) .withApiHost("http://") .withApiKey("6439e059e16") .configure(); EventBus.getDefault().post("initSuccess"); EventBus.getDefault().unregister(this); } } } /** * @Created by xww. * @Creation time 2018/8/25. */ public class SplashActivity extends AppCompatActivity { private static final String TAG = "SplashActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EventBus.getDefault().register(this); EventBus.getDefault().post("initConfigurations"); } @Subscribe public void startMainActivity(String event) { if ("initSuccess".equals(event)) { //在這裡載入所需庫完成,進入主介面 startActivity(new Intent(SplashActivity.this, WeatherActivity.class)); finish(); } } @Override protected void onDestroy() { super.onDestroy(); EventBus.getDefault().unregister(this); } /** * 遮蔽了返回鍵,避免在閃屏頁中退出app */ @Override public void onBackPressed() { } }
我們的Log也可以很好的說明它們的執行順序,成功的印證我們的思路是正確的。
這樣的話,我們可以在啟動 splash 頁面載入一下庫,然後載入完成後,進入主頁面,由於資源都初始化好了,自然用起來就快一點,效果圖:
這裡我們點選桌面圖示時,一啟動的就是我們的 splash 的一張圖,而不是白茫茫的背景了,看起來舒服了許多。
都看到這裡了,各位看官點個關注唄!