新聞中心
前言

創(chuàng)新互聯(lián)公司是專業(yè)的桃源網(wǎng)站建設(shè)公司,桃源接單;提供成都做網(wǎng)站、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行桃源網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
今天朋友遇到一個(gè)面試題,分享給大家:
onStart生命周期表示Activity可見(jiàn),那為什么不能交互呢?
這個(gè)問(wèn)題看似簡(jiǎn)單,但涉及到的面還是比較多的,比如Activity生命周期的理解,進(jìn)程的理解,以及View繪制的時(shí)機(jī)。
一起看看吧。
onStart介紹
首先,是關(guān)于onStart生命周期的理解。
官網(wǎng)是這么介紹的:
當(dāng) Activity 進(jìn)入“已開(kāi)始”狀態(tài)時(shí),系統(tǒng)會(huì)調(diào)用此回調(diào)。onStart() 調(diào)用使 Activity 對(duì)用戶可見(jiàn),因?yàn)閼?yīng)用會(huì)為 Activity 進(jìn)入前臺(tái)并支持互動(dòng)做準(zhǔn)備。
對(duì)用戶可見(jiàn)?
奇怪了,對(duì)用戶可見(jiàn),不就是我們可以看到了嗎,為什么又不能互動(dòng)呢?
更何況onStart 的時(shí)候界面都還沒(méi)繪制,該怎么理解這個(gè)可見(jiàn)呢?
做個(gè)小實(shí)驗(yàn)
首先,科普官方定義的兩個(gè)狀態(tài)。
- onStart到onStop中間的狀態(tài)叫做“已開(kāi)始”狀態(tài)。
- onResume到onPause中間的狀態(tài)叫做“已恢復(fù)”狀態(tài)。
然后我們做個(gè)小實(shí)驗(yàn),定義ActivityA 和 ActivityB,ActivityB為Dialog主題,ActivityA中點(diǎn)擊可以跳轉(zhuǎn)到B:
- image.setOnClickListener {
- startActivity(Intent(this, ActivityB::class.java))
- }
- android:theme="@style/Theme.AppCompat.Light.Dialog"
- android:launchMode="standard">
進(jìn)入ActivityA后,點(diǎn)擊按鈕,跳轉(zhuǎn)到B,這時(shí)候A的生命周期走到了onPause,也就是回到了已開(kāi)始狀態(tài)。
這個(gè)時(shí)候,界面是這個(gè)樣子:
ActivityA處在已開(kāi)始狀態(tài),對(duì)用戶可見(jiàn)。
這里的可見(jiàn)是不是就很好理解了,確實(shí)對(duì)我們可見(jiàn)了,只不過(guò) 不在前臺(tái),不能交互。
所以延伸到普通的Activity,這個(gè)可見(jiàn),并不是表示用戶能用肉眼看到了,而是想表達(dá):
Activity已經(jīng)顯示出來(lái)了,但是還不在前臺(tái),所以只是可見(jiàn),但不可交互。
這個(gè)可見(jiàn)狀態(tài)是從onStart開(kāi)始,onStop結(jié)束,我們可以分為兩個(gè)階段:
- onStart到onResume。這個(gè)階段,Activity被創(chuàng)建,布局已加載,但是界面還沒(méi)繪制,可以說(shuō)界面都不存在。
- onPause到onStop。這個(gè)階段,就是我們剛才所做的實(shí)驗(yàn),Activity有界面,只是被新的界面所遮擋,也就是不在前臺(tái)。
所以綜合兩個(gè)階段,我們把這種Activity被創(chuàng)建或已經(jīng)顯示出來(lái),但是不在前臺(tái),介于兩者之間的狀態(tài)叫做 可見(jiàn) 狀態(tài)。
onStart 和 onResume
到此,我們知道了可見(jiàn)的意思,其實(shí)也就知道了另外一個(gè)問(wèn)題,也就是為什么要設(shè)計(jì)出onStart和onResume這兩種狀態(tài)。
- onStart和onStop,是從Activity是否可見(jiàn)的角度設(shè)計(jì)的。
- onResume和onPause,是從Activity是否位于前臺(tái)的角度設(shè)計(jì)的。
所以Activity的生命周期又可以解釋為:
被創(chuàng)建(onCreate)——> 可見(jiàn)(onStart)——> 位于前臺(tái)(onResume)——> 可見(jiàn)但不在前臺(tái)(onPause)
可見(jiàn)進(jìn)程
從另外的角度看,這個(gè)可見(jiàn) 可以指的是 可見(jiàn)進(jìn)程。這就涉及到進(jìn)程的分類。
為了確定在內(nèi)存不足時(shí)應(yīng)該終止哪些進(jìn)程,Android 會(huì)根據(jù)每個(gè)進(jìn)程中運(yùn)行的組件以及這些組件的狀態(tài),將它們放入“重要性層次結(jié)構(gòu)”。這些進(jìn)程類型包括(按重要性排序):前臺(tái)進(jìn)程,可見(jiàn)進(jìn)程,服務(wù)流程,緩存進(jìn)程
這些進(jìn)程是什么意思呢?
- 前臺(tái)進(jìn)程是用戶目前執(zhí)行操作所需的進(jìn)程。比如 正在用戶的互動(dòng)屏幕上運(yùn)行一個(gè) Activity(其 onResume() 方法已被調(diào)用)
- 可見(jiàn)進(jìn)程是正在進(jìn)行用戶當(dāng)前知曉的任務(wù)。比如 正在運(yùn)行的 Activity 在屏幕上對(duì)用戶可見(jiàn),但不在前臺(tái)(其 onPause() 方法已被調(diào)用)
- 服務(wù)流程包含一個(gè)已使用 startService() 方法啟動(dòng)的 Service。
- 緩存進(jìn)程是目前不需要的進(jìn)程。比如 當(dāng)前不可見(jiàn)的一個(gè)或多個(gè) Activity 實(shí)例(onStop() 方法已被調(diào)用并返回)
所以Activity的生命周期又可以通過(guò)進(jìn)程分為:
可見(jiàn)進(jìn)程(onStart)——> 前臺(tái)進(jìn)程(onResume)——> 可見(jiàn)進(jìn)程(onPause)——> 緩存進(jìn)程(onStop)
這些進(jìn)程有什么用呢?
我們都知道,在Android系統(tǒng)中有很多很多運(yùn)行中的APP,也就代表了不同的進(jìn)程。
當(dāng)內(nèi)存不夠時(shí)(達(dá)到了某個(gè)閾值),系統(tǒng)首先會(huì)通過(guò)onTrimMemory()回調(diào)方法告訴應(yīng)用,讓?xiě)?yīng)用自己來(lái)處理低內(nèi)存情況下的減少內(nèi)存操作。這之后,如果內(nèi)存還是很緊張,那么就會(huì)開(kāi)始對(duì)一些進(jìn)程的殺除,以釋放內(nèi)存。這里就需要判斷進(jìn)程的優(yōu)先級(jí)了,從低優(yōu)先級(jí)開(kāi)始按順序終止進(jìn)程。
所以,進(jìn)程的分類作用就在這了。優(yōu)先級(jí)的高低其實(shí)就代表了 終止進(jìn)程的順序,也代表了對(duì)用戶的影響程度。
當(dāng)然實(shí)際代碼中,進(jìn)程優(yōu)先級(jí)是有數(shù)字表示的,也就是ADJ,而上面說(shuō)的進(jìn)程類型都有相應(yīng)的進(jìn)程優(yōu)先級(jí)數(shù)字范圍。比如:
- public final class ProcessList {
- //可見(jiàn)進(jìn)程
- static final int VISIBLE_APP_ADJ = 100;
- // 前臺(tái)進(jìn)程
- static final int FOREGROUND_APP_ADJ = 0;
- // 服務(wù)進(jìn)程
- static final int SERVICE_ADJ = 500;
- // 緩存進(jìn)程
- static final int CACHED_APP_MIN_ADJ = 900;
- //...
- }
再回到我們的問(wèn)題上來(lái):
其中,可見(jiàn)進(jìn)程這里也出現(xiàn)了可見(jiàn)的概念,給出的解釋是:用戶知曉。
當(dāng)我們點(diǎn)擊一個(gè)頁(yè)面,我們知道這個(gè)頁(yè)面將要顯示出來(lái),也知道之前的頁(yè)面在這個(gè)頁(yè)面后面。所以這些頁(yè)面和進(jìn)程都是我們所知曉的,只是不在前臺(tái)。
所以onStart表示的可見(jiàn),也可以理解為可見(jiàn)進(jìn)程,意思是這個(gè)Activity所在的進(jìn)程任務(wù)已經(jīng)被創(chuàng)建并顯示,我們知曉它,只是沒(méi)在前臺(tái)。
可交互
那么可以交互到底是發(fā)生在什么階段呢?
之前我們說(shuō)過(guò),在Activity啟動(dòng)過(guò)程中,調(diào)用了handleResumeActivity方法。在這個(gè)方法中,調(diào)用了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才被繪制出來(lái),并顯示到前臺(tái)。
官網(wǎng)是這么解釋onResume的:
Activity 會(huì)在進(jìn)入“已恢復(fù)”狀態(tài)時(shí)來(lái)到前臺(tái),然后系統(tǒng)調(diào)用 onResume() 回調(diào)。這是應(yīng)用與用戶互動(dòng)的狀態(tài)。應(yīng)用會(huì)一直保持這種狀態(tài),直到某些事件發(fā)生,讓焦點(diǎn)遠(yuǎn)離應(yīng)用。此類事件包括接到來(lái)電、用戶導(dǎo)航到另一個(gè) Activity,或設(shè)備屏幕關(guān)閉。
所以可交互狀態(tài)應(yīng)該是在onResume之后,也就是Activity可見(jiàn)并且處于前臺(tái)。
小結(jié)
總結(jié)下:
onStart狀態(tài)表示Activity可見(jiàn),而可見(jiàn)表示的意思是Activity被創(chuàng)建出來(lái)了,被用戶所知曉,但是不在前臺(tái),還沒(méi)繪制界面,所以無(wú)法交互。也可以意指其所在的進(jìn)程為可見(jiàn)進(jìn)程。
其可見(jiàn)之意應(yīng)該和onStop一起使用,即onStart到onStop這個(gè)階段叫做 可見(jiàn) 階段。
而真正顯示出來(lái)可以進(jìn)行交互 發(fā)生在onResume之后,也就是View繪制出來(lái),并處于前臺(tái)的時(shí)候。
參考
《Android開(kāi)發(fā)藝術(shù)探索》 https://juejin.cn/post/6896751245722615815 https://juejin.cn/post/6891911483379482637
本文轉(zhuǎn)載自微信公眾號(hào)「碼上積木」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系碼上積木公眾號(hào)。
網(wǎng)站欄目:怎么理解onStart可見(jiàn)但不可交互
標(biāo)題URL:http://www.dlmjj.cn/article/dhopdid.html


咨詢
建站咨詢
