App啟動方式
如何啟動App呢?
說到底就是點擊屏幕的App圖標(biāo)腾仅。但是點擊的時候會發(fā)現(xiàn)有時進入App首頁很快,有時很慢套利,有時中間還有個白屏推励。有時中間還有個黑屏。
造成這樣的情況肉迫,是什么原因呢验辞?我們先從App啟動的方式開始說起。
冷啟動
熱啟動
冷啟動
冷啟動:當(dāng)啟動應(yīng)用時喊衫,后臺沒有該應(yīng)用的進程跌造,這時系統(tǒng)會重新創(chuàng)建一個新的進程分配給該應(yīng)用。
冷啟動的特點:因為系統(tǒng)會重新創(chuàng)建一個新的進程分配給它族购,所以會創(chuàng)建和初始化Application壳贪,在創(chuàng)建和初始化它的Launch Activity(onCreate onMesure onLayout,ondraw),最后展示在界面上
熱啟動
熱啟動:當(dāng)啟動應(yīng)用時寝杖,后臺存在該應(yīng)用的進程(back鍵违施,home鍵,應(yīng)用退出瑟幕,但是沒有銷毀)磕蒲,從已有的進程中啟動
熱啟動的特點:從已有的進程中啟動留潦,不需要創(chuàng)建和初始化Application ,直接創(chuàng)建和初始化它的Launch Activity
<mark>兩者區(qū)別:后臺進程是否存在相應(yīng)的進程,創(chuàng)建進程是耗時操作</mark>
應(yīng)用的啟動過程
主要講解冷啟動的情況(分配進程->創(chuàng)建和初始化Application->創(chuàng)建和初始化Launch Activity)
可以參考老羅的Android之旅-Android應(yīng)用程序啟動過程源代碼分析
我這里做了下摘要辣往,App啟動過程就是:
整個應(yīng)用程序的啟動過程要執(zhí)行很多步驟兔院,但是整體來看,主要分為以下五個階段:
一. Step1 - Step 11:
Launcher通過Binder進程間通信機制通知ActivityManagerService排吴,
它要啟動一個Activity秆乳;
二. Step 12 - Step 16:
ActivityManagerService通過Binder進程間通信機制通知Launcher進入Paused狀態(tài);
三. Step 17 - Step 24:
Launcher通過Binder進程間通信機制通知ActivityManagerService钻哩,它已經(jīng)準(zhǔn)備就緒進入Paused狀態(tài)屹堰,
于是ActivityManagerService就創(chuàng)建一個新的進程,用來啟動一個ActivityThread實例街氢,
即將要啟動的Activity就是在這個ActivityThread實例中運行扯键;
四. Step 25 - Step 27:
ActivityThread通過Binder進程間通信機制將一個ApplicationThread類型的Binder對象傳遞給ActivityManagerService,
以便以后ActivityManagerService能夠通過這個Binder對象和它進行通信珊肃;
五. Step 28 - Step 35:
ActivityManagerService通過Binder進程間通信機制通知ActivityThread荣刑,
現(xiàn)在一切準(zhǔn)備就緒,它可以真正執(zhí)行Activity的啟動操作了伦乔。
<mark>有興趣可以看下源碼實現(xiàn)厉亏,其實App的啟動相當(dāng)于在Launch 這個應(yīng)用中點擊某個圖標(biāo)進行跳轉(zhuǎn)</mark>
ActivityManagerService就創(chuàng)建一個新的進程,用來啟動一個ActivityThread實例
--可以理解成Zygote進程中fork一個新的進程分配給應(yīng)用.至于Zygote是什么呢烈和?我還沒搞懂呢爱只。推薦兩篇博客大家自行理解下
Android深入淺出之Zygote
Android系統(tǒng)進程Zygote啟動過程的源代碼分析
后續(xù)理解了,會專門講解下
如何測量應(yīng)用啟動時間
- 可以通過代碼打樁招刹,計算啟動時間
- 可以通過秒表計算(肉眼觀察恬试,這個很low)
最近查到資料,android是有命令可以計算啟動時間的
adb shell am start -W [packageName]/[packageName.launchActivity]
OK疯暑,那就拿自己的項目來給大家看看上面兩種啟動的時間差別
冷啟動:
熱啟動
<mark>兩者差距時間很多训柴,只能說明在Application做了很多耗時的操作.并且現(xiàn)在大部分的App啟動是冷啟動,因為用戶的習(xí)慣就是不喜歡有這么多后臺進程妇拯,他們喜歡刪掉所有進程
提醒:
<mark>避免一些耗時操作在Application中處理幻馁,并減少LaunchActivity的View層級,減少View測量繪制時間
App啟動為什么會白屏乖阵,黑屏
回到剛開始的問題宣赔,為什么有時打開App會出現(xiàn)白屏/黑屏情況
先來解釋下為什么會出現(xiàn)白屏/黑屏的原因?
是因為已進入到Activity,但是未加載到布局文件瞪浸,
就先顯示來windows窗口的背景儒将。
黑屏/白屏就是顯示的windows背景(這個就是theme的設(shè)置)
解決方案:
1.為 Theme 設(shè)置背景圖;
(會給人一種快速加載的感覺)
<style name="Theme.AppStartLoad" parent="android:Theme">
<item name="android:windowBackground">@drawable/ipod_bg</item>
<item name="android:windowNoTitle">true</item>
</style>
2.為 Theme 設(shè)置透明屬性
(回給人較慢加載出來感覺对蒲,因為需要等布局加載完之后一次性展開)
<style name="Theme.AppStartLoadTranslucent" parent="android:Theme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
</style>
這里不展開了钩蚊,可以看下這個Android開發(fā)之解決APP啟動白屏或者黑屏閃現(xiàn)的問題
優(yōu)化冷啟動時間的小技巧
按照剛才說的為什么出現(xiàn)白屏/黑屏原因的解決方案贡翘。
其實可以在給啟動的Activity的Theme中背景設(shè)置為啟動頁的圖片,然后在等待加載完activtity的布局后砰逻,恢復(fù)原來的theme
代碼舉例:
在style.xml文件
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/appstart_background
</item>
<!--<item name="android:windowIsTranslucent">true</item>-->
</style>
在AndroidManifest.xml
<activity android:name=".AppStartActivity"
android:theme="@style/AppTheme.Launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
AppStartActivity.java
public class AppStartActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
setContentView(R.layout.activity_appstart);
}
}
上面的@drawable/appstart_background就是啟動頁的默認背景鸣驱。親測,可用