今天朋友遇到一個面試題,分享給你們:java
onStart生命週期表示Activity可見,那爲何不能交互呢?android
這個問題看似簡單,但涉及到的面仍是比較多的,好比Activity生命週期的理解,進程的理解,以及View繪製的時機。面試
一塊兒看看吧。緩存
首先,是關於onStart生命週期的理解。架構
官網是這麼介紹的:ide
當 Activity 進入「已開始」狀態時,系統會調用此回調。onStart() 調用使 Activity 對用戶可見,由於應用會爲 Activity 進入前臺並支持互動作準備。佈局
對用戶可見?post
奇怪了,對用戶可見,不就是咱們能夠看到了嗎,爲何又不能互動呢?該怎麼理解這個可見呢?學習
首先,科普官方定義的兩個狀態。this
「已開始」
狀態。「已恢復」
狀態。而後咱們作個小實驗,定義ActivityA
和 ActivityB
,ActivityB
爲Dialog主題,ActivityA
中點擊能夠跳轉到B:
image.setOnClickListener { startActivity(Intent(this, ActivityB::class.java)) } <activity android:name=".activity.ActivityB" android:theme="@style/Theme.AppCompat.Light.Dialog" android:launchMode="standard"> </activity>
進入ActivityA後,點擊按鈕,跳轉到B,這時候A的生命週期走到了onPause
,也就是回到了已開始
狀態。
這個時候,界面是這個樣子:
ActivityA處在已開始狀態,對用戶可見。
這裏的可見是否是就很好理解了,確實對咱們可見了,只不過 不在前臺,不能交互。
因此延伸到普通的Activity
,這個可見,並非表示用戶能用肉眼看到了,而是想表達:
Activity
已經顯示出來了,可是還不在前臺
,因此只是可見
,但不可交互。
這個可見狀態是從onStart開始,onStop結束,咱們能夠分爲兩個階段:
因此綜合兩個階段,咱們把這種Activity被建立或已經顯示出來,可是不在前臺,介於二者之間的狀態叫作 可見
狀態。
到此,咱們知道了可見的意思,其實也就知道了另一個問題,也就是爲何要設計出onStart和onResume這兩種狀態。
onStart和onStop
,是從Activity是否可見的角度設計的。onResume和onPause
,是從Activity是否位於前臺的角度設計的。因此Activity
的生命週期又能夠解釋爲:
被建立(onCreate)——> 可見(onStart)——> 位於前臺(onResume)——> 可見但不在前臺(onPause)
從另外的角度看,這個可見 能夠指的是 可見進程。
這就涉及到進程的分類。
爲了肯定在內存不足時應該終止哪些進程,Android 會根據每一個進程中運行的組件以及這些組件的狀態,將它們放入「重要性層次結構」。這些進程類型包括(按重要性排序):前臺進程,可見進程,服務流程,緩存進程
這些進程是什麼意思呢?
前臺進程
是用戶目前執行操做所需的進程。好比 正在用戶的互動屏幕上運行一個 Activity(其 onResume() 方法已被調用)可見進程
是正在進行用戶當前知曉的任務。好比 正在運行的 Activity 在屏幕上對用戶可見,但不在前臺(其 onPause() 方法已被調用)服務流程
包含一個已使用 startService() 方法啓動的 Service。緩存進程
是目前不須要的進程。好比 當前不可見的一個或多個 Activity 實例(onStop() 方法已被調用並返回)因此Activity的生命週期又能夠經過進程分爲:
可見進程(onStart)——> 前臺進程(onResume)——> 可見進程(onPause)——> 緩存進程(onStop)
這些進程有什麼用呢?
咱們都知道,在Android系統中有不少不少運行中的APP,也就表明了不一樣的進程。
當內存不夠時(達到了某個閾值),系統首先會經過onTrimMemory()回調方法告訴應用,讓應用本身來處理低內存狀況下的減小內存操做。
這以後,若是內存仍是很緊張,那麼就會開始對一些進程的殺除,以釋放內存。這裏就須要判斷進程的優先級了,從低優先級開始按順序終止進程。
因此,進程的分類做用就在這了。優先級的高低其實就表明了 終止進程的順序,也表明了對用戶的影響程度。
固然實際代碼中,進程優先級是有數字表示的,也就是ADJ,而上面說的進程類型都有相應的進程優先級數字範圍。好比:
public final class ProcessList { //可見進程 static final int VISIBLE_APP_ADJ = 100; // 前臺進程 static final int FOREGROUND_APP_ADJ = 0; // 服務進程 static final int SERVICE_ADJ = 500; // 緩存進程 static final int CACHED_APP_MIN_ADJ = 900; //... }
再回到咱們的問題上來:
其中,可見進程這裏也出現了可見的概念,給出的解釋是:用戶知曉
。
當咱們點擊一個頁面,咱們知道這個頁面將要顯示出來,也知道以前的頁面在這個頁面後面。因此這些頁面和進程都是咱們所知曉的,只是不在前臺。
因此onStart
表示的可見,也能夠理解爲可見進程
,意思是這個Activity所在的進程任務已經被建立並顯示,咱們知曉它,只是沒在前臺。
那麼能夠交互究竟是發生在什麼階段呢?
以前咱們說過,在Activity啓動過程當中,調用了handleResumeActivity
方法。在這個方法中,調用了onResume
方法和addView
方法,完成了View的第一次繪製,並顯示到界面上。
@Override public void handleResumeActivity() { //onResume final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason); //addView if (r.window == null && !a.mFinished && willBeVisible) { wm.addView(decor, l); } }
因此到onResume,View才被繪製出來,並顯示到前臺。
官網是這麼解釋onResume
的:
Activity 會在進入「已恢復」狀態時來到前臺,而後系統調用 onResume() 回調。這是應用與用戶互動的狀態。應用會一直保持這種狀態,直到某些事件發生,讓焦點遠離應用。此類事件包括接到來電、用戶導航到另外一個 Activity,或設備屏幕關閉。
因此可交互狀態應該是在onResume
以後,也就是Activity
可見而且處於前臺。
總結下:
onStart
狀態表示Activity
可見,而可見表示的意思是Activity
被建立出來了,被用戶所知曉,可是不在前臺,還沒繪製界面,因此沒法交互。也能夠意指其所在的進程爲可見進程。
其可見之意應該和onStop
一塊兒使用,即onStart
到onStop
這個階段叫作 可見 階段。
而真正顯示出來能夠進行交互 發生在onResume
以後,也就是View繪製出來,並處於前臺的時候。
《Android開發藝術探索》
https://juejin.cn/post/6896751245722615815
https://juejin.cn/post/6891911483379482637
感謝你們的閱讀,有一塊兒學習的小夥伴能夠關注下個人公衆號——碼上積木❤️❤️
每日一個知識點,聚沙成塔,創建知識體系架構。
這裏有一羣很好的Android小夥伴,歡迎你們加入~