日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

android代理生命周期,了解 Activity 生命周期

發(fā)布時(shí)間:2024/7/5 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android代理生命周期,了解 Activity 生命周期 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

當(dāng)用戶(hù)瀏覽、退出和返回到您的應(yīng)用時(shí),您應(yīng)用中的

在生命周期回調(diào)方法中,您可以聲明用戶(hù)離開(kāi)和再次進(jìn)入 Activity 時(shí) Activity 的行為方式。例如,如果您正構(gòu)建流媒體視頻播放器,當(dāng)用戶(hù)切換至另一應(yīng)用時(shí),您可能要暫停視頻或終止網(wǎng)絡(luò)連接。當(dāng)用戶(hù)返回時(shí),您可以重新連接網(wǎng)絡(luò)并允許用戶(hù)從同一位置繼續(xù)播放視頻。換言之,每個(gè)回調(diào)都支持您執(zhí)行適合給定狀態(tài)變更的特定作業(yè)。在合適的時(shí)間執(zhí)行正確的作業(yè),并妥善處理轉(zhuǎn)換,這將提升應(yīng)用的穩(wěn)健性和性能。例如,良好的生命周期回調(diào)實(shí)現(xiàn)有助于防止應(yīng)用出現(xiàn)以下問(wèn)題:

當(dāng)用戶(hù)在使用應(yīng)用時(shí)接聽(tīng)來(lái)電,或切換至另一應(yīng)用時(shí)崩潰。

當(dāng)用戶(hù)未主動(dòng)使用它時(shí),消耗寶貴的系統(tǒng)資源。

當(dāng)用戶(hù)離開(kāi)應(yīng)用并在稍后返回時(shí),丟失用戶(hù)的進(jìn)度。

當(dāng)屏幕在橫向和縱向之間旋轉(zhuǎn)時(shí),崩潰或丟失用戶(hù)的進(jìn)度。

本文檔將詳細(xì)介紹 Activity 生命周期。首先介紹生命周期范例。接著介紹每個(gè)回調(diào):它們執(zhí)行時(shí)內(nèi)部發(fā)生了什么,以及您應(yīng)該在執(zhí)行期間實(shí)現(xiàn)什么。然后,簡(jiǎn)要介紹 Activity 狀態(tài)與導(dǎo)致進(jìn)程被系統(tǒng)終止的漏洞之間的關(guān)系。最后,討論與在 Activity 狀態(tài)之間轉(zhuǎn)換相關(guān)的若干主題。

如需了解有關(guān)處理生命周期的信息(包括最佳做法的相關(guān)指導(dǎo)),請(qǐng)參閱使用生命周期感知型組件處理生命周期和保存界面狀態(tài)。如需了解如何將 Activity 與架構(gòu)組件結(jié)合使用,以構(gòu)建生產(chǎn)質(zhì)量的穩(wěn)健應(yīng)用,請(qǐng)參閱應(yīng)用架構(gòu)指南。

Activity 生命周期概念

為了在 Activity 生命周期的各個(gè)階段之間導(dǎo)航轉(zhuǎn)換,Activity 類(lèi)提供六個(gè)核心回調(diào):

圖 1 是對(duì)此范例的直觀展現(xiàn)。

圖 1. Activity 生命周期的簡(jiǎn)化圖示。

當(dāng)用戶(hù)開(kāi)始離開(kāi) Activity 時(shí),系統(tǒng)會(huì)調(diào)用方法來(lái)銷(xiāo)毀該 Activity。在某些情況下,此銷(xiāo)毀只是部分銷(xiāo)毀;Activity 仍然駐留在內(nèi)存中(例如當(dāng)用戶(hù)切換至另一應(yīng)用時(shí)),并且仍然可以返回到前臺(tái)。如果用戶(hù)返回到該 Activity,Activity 會(huì)從用戶(hù)離開(kāi)時(shí)的位置繼續(xù)運(yùn)行。除了少數(shù)例外,應(yīng)用在后臺(tái)運(yùn)行時(shí)會(huì)受到限制,無(wú)法啟動(dòng) Activity。

系統(tǒng)終止給定進(jìn)程及其中 Activity 的可能性取決于當(dāng)時(shí) Activity 的狀態(tài)。Activity 狀態(tài)和從內(nèi)存中彈出 會(huì)更詳細(xì)地介紹狀態(tài)與彈出漏洞之間的關(guān)系。

根據(jù) Activity 的復(fù)雜程度,您可能不需要實(shí)現(xiàn)所有生命周期方法。但是,請(qǐng)務(wù)必了解每個(gè)方法,并實(shí)現(xiàn)能夠確保應(yīng)用按用戶(hù)預(yù)期方式運(yùn)行的方法,這非常重要。

在下一部分中,本文檔將詳細(xì)介紹用于處理狀態(tài)間轉(zhuǎn)換的回調(diào)。

生命周期回調(diào)

本部分介紹 Activity 生命周期中所用回調(diào)方法的相關(guān)概念及實(shí)現(xiàn)信息。

某些操作(例如調(diào)用 setContentView())屬于 Activity 生命周期方法本身。不過(guò),用于實(shí)現(xiàn)依賴(lài)組件操作的代碼應(yīng)放在組件本身內(nèi)。為此,您必須使依賴(lài)組件具有生命周期感知能力。請(qǐng)參閱使用生命周期感知型組件處理生命周期,了解如何讓您的依賴(lài)組件獲得生命周期感知能力。

onCreate()

您必須實(shí)現(xiàn)此回調(diào),它會(huì)在系統(tǒng)首次創(chuàng)建 Activity 時(shí)觸發(fā)。Activity 會(huì)在創(chuàng)建后進(jìn)入“已創(chuàng)建”狀態(tài)。在 onCreate() 的實(shí)現(xiàn)可能會(huì)將數(shù)據(jù)綁定到列表,將 Activity 與 ViewModel 相關(guān)聯(lián),并實(shí)例化某些類(lèi)作用域變量。此方法會(huì)接收 savedInstanceState 參數(shù),后者是包含 Activity 先前保存狀態(tài)的

如果您有一個(gè)生命周期感知型組件與您的 Activity 生命周期相關(guān)聯(lián),該組件將收到 ON_CREATE 事件。系統(tǒng)將調(diào)用帶有 @OnLifecycleEvent 注釋的方法,以使您的生命周期感知型組件可以執(zhí)行已創(chuàng)建狀態(tài)所需的任何設(shè)置代碼。

R.layout.main_activity 傳遞給

Kotlin

lateinit var textView: TextView

// some transient state for the activity instance

var gameState: String? = null

override fun onCreate(savedInstanceState: Bundle?) {

// call the super class onCreate to complete the creation of activity like

// the view hierarchy

super.onCreate(savedInstanceState)

// recovering the instance state

gameState = savedInstanceState?.getString(GAME_STATE_KEY)

// set the user interface layout for this activity

// the layout file is defined in the project res/layout/main_activity.xml file

setContentView(R.layout.main_activity)

// initialize member TextView so we can manipulate it later

textView = findViewById(R.id.text_view)

}

// This callback is called only when there is a saved instance that is previously saved by using

// onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore

// other state here, possibly usable after onStart() has completed.

// The savedInstanceState Bundle is same as the one used in onCreate().

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {

textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY)

}

// invoked when the activity may be temporarily destroyed, save the instance state here

override fun onSaveInstanceState(outState: Bundle?) {

outState?.run {

putString(GAME_STATE_KEY, gameState)

putString(TEXT_VIEW_KEY, textView.text.toString())

}

// call superclass to save any view hierarchy

super.onSaveInstanceState(outState)

}Java

TextView textView;

// some transient state for the activity instance

String gameState;

@Override

public void onCreate(Bundle savedInstanceState) {

// call the super class onCreate to complete the creation of activity like

// the view hierarchy

super.onCreate(savedInstanceState);

// recovering the instance state

if (savedInstanceState != null) {

gameState = savedInstanceState.getString(GAME_STATE_KEY);

}

// set the user interface layout for this activity

// the layout file is defined in the project res/layout/main_activity.xml file

setContentView(R.layout.main_activity);

// initialize member TextView so we can manipulate it later

textView = (TextView) findViewById(R.id.text_view);

}

// This callback is called only when there is a saved instance that is previously saved by using

// onSaveInstanceState(). We restore some state in onCreate(), while we can optionally restore

// other state here, possibly usable after onStart() has completed.

// The savedInstanceState Bundle is same as the one used in onCreate().

@Override

public void onRestoreInstanceState(Bundle savedInstanceState) {

textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY));

}

// invoked when the activity may be temporarily destroyed, save the instance state here

@Override

public void onSaveInstanceState(Bundle outState) {

outState.putString(GAME_STATE_KEY, gameState);

outState.putString(TEXT_VIEW_KEY, textView.getText());

// call superclass to save any view hierarchy

super.onSaveInstanceState(outState);

}

除了定義 XML 文件,然后將其傳遞給 界面文檔。

您的 Activity 并未處于“已創(chuàng)建”狀態(tài)。下一部分將介紹

onStart()

當(dāng) Activity 進(jìn)入“已開(kāi)始”狀態(tài)時(shí),系統(tǒng)會(huì)調(diào)用此回調(diào)。

當(dāng) Activity 進(jìn)入已開(kāi)始狀態(tài)時(shí),與 Activity 生命周期相關(guān)聯(lián)的所有生命周期感知型組件都將收到 ON_START 事件。

onResume()

Activity 會(huì)在進(jìn)入“已恢復(fù)”狀態(tài)時(shí)來(lái)到前臺(tái),然后系統(tǒng)調(diào)用

當(dāng) Activity 進(jìn)入已恢復(fù)狀態(tài)時(shí),與 Activity 生命周期相關(guān)聯(lián)的所有生命周期感知型組件都將收到 ON_RESUME 事件。這時(shí),生命周期組件可以啟用在組件可見(jiàn)且位于前臺(tái)時(shí)需要運(yùn)行的任何功能,例如啟動(dòng)相機(jī)預(yù)覽。

當(dāng)發(fā)生中斷事件時(shí),Activity 進(jìn)入“已暫停”狀態(tài),系統(tǒng)調(diào)用

如果 Activity 從“已暫?!睜顟B(tài)返回“已恢復(fù)”狀態(tài),系統(tǒng)將再次調(diào)用 onPause() 期間釋放的組件,并執(zhí)行每次 Activity 進(jìn)入“已恢復(fù)”狀態(tài)時(shí)必須完成的任何其他初始化操作。

以下是生命周期感知型組件的示例,該組件在收到 ON_RESUME 事件時(shí)訪問(wèn)相機(jī):

Kotlin

class CameraComponent : LifecycleObserver {

...

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)

fun initializeCamera() {

if (camera == null) {

getCamera()

}

}

...

}Java

public class CameraComponent implements LifecycleObserver {

...

@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)

public void initializeCamera() {

if (camera == null) {

getCamera();

}

}

...

}

LifecycleObserver 收到 ON_RESUME 事件后,上述代碼便會(huì)初始化相機(jī)。然而,在多窗口模式下,即使處于“已暫?!睜顟B(tài),您的 Activity 也可能完全可見(jiàn)。例如,當(dāng)用戶(hù)處于多窗口模式,并點(diǎn)按另一個(gè)不包含 Activity 的窗口時(shí),您的 Activity 將進(jìn)入“已暫?!睜顟B(tài)。如果您希望相機(jī)僅在應(yīng)用處于“已恢復(fù)”(可見(jiàn)且在前臺(tái)運(yùn)行)狀態(tài)時(shí)可用,請(qǐng)?jiān)谑盏缴鲜?ON_RESUME 事件后初始化相機(jī)。如果您希望在 Activity 處于“已暫?!睜顟B(tài)但可見(jiàn)時(shí)(例如在多窗口模式下)保持相機(jī)可用,應(yīng)在收到 ON_START 事件后初始化相機(jī)。但請(qǐng)注意,若要讓相機(jī)在 Activity 處于“已暫?!睜顟B(tài)時(shí)可用,可能會(huì)導(dǎo)致系統(tǒng)在多窗口模式下拒絕其他處于“已恢復(fù)”狀態(tài)的應(yīng)用訪問(wèn)相機(jī)。有時(shí)可能有必要讓相機(jī)在 Activity 處于“已暫?!睜顟B(tài)時(shí)保持可用,但這樣做實(shí)際可能會(huì)降低整體用戶(hù)體驗(yàn)。請(qǐng)仔細(xì)考慮,生命周期的哪個(gè)階段更適合在多窗口環(huán)境下控制共享系統(tǒng)資源。如需詳細(xì)了解如何支持多窗口模式,請(qǐng)參閱多窗口支持。

無(wú)論您選擇在哪個(gè)構(gòu)建事件中執(zhí)行初始化操作,都請(qǐng)務(wù)必使用相應(yīng)的生命周期事件來(lái)釋放資源。如果您在收到 ON_START 事件后初始化某些內(nèi)容,請(qǐng)?jiān)谑盏?ON_STOP 事件后釋放或終止相應(yīng)內(nèi)容。如果您在收到 ON_RESUME 事件后初始化某些內(nèi)容,請(qǐng)?jiān)谑盏?ON_PAUSE 事件后將其釋放。

請(qǐng)注意,上述代碼段將相機(jī)初始化代碼放置在生命周期感知型組件中。您也可以直接將此代碼放入 Activity 生命周期回調(diào)(例如 onStart() 和 onStop()),但我們不建議您這樣做。通過(guò)將此邏輯添加到獨(dú)立的生命周期感知型組件中,您可以對(duì)多個(gè) Activity 重復(fù)使用該組件,而無(wú)需復(fù)制代碼。請(qǐng)參閱使用生命周期感知型組件處理生命周期,了解如何創(chuàng)建生命周期感知型組件。

onPause()

系統(tǒng)將此方法視為用戶(hù)將要離開(kāi)您的 Activity 的第一個(gè)標(biāo)志(盡管這并不總是意味著 Activity 會(huì)被銷(xiāo)毀);此方法表示 Activity 不再位于前臺(tái)(盡管在用戶(hù)處于多窗口模式時(shí) Activity 仍然可見(jiàn))。使用 onPause() 方法暫?;蛘{(diào)整當(dāng) Activity 處于“已暫停”狀態(tài)時(shí)不應(yīng)繼續(xù)(或應(yīng)有節(jié)制地繼續(xù))的操作,以及您希望很快恢復(fù)的操作。Activity 進(jìn)入此狀態(tài)的原因有很多。例如:

如 onResume() 部分所述,某個(gè)事件會(huì)中斷應(yīng)用執(zhí)行。這是最常見(jiàn)的情況。

在 Android 7.0(API 級(jí)別 24)或更高版本中,有多個(gè)應(yīng)用在多窗口模式下運(yùn)行。無(wú)論何時(shí),都只有一個(gè)應(yīng)用(窗口)可以擁有焦點(diǎn),因此系統(tǒng)會(huì)暫停所有其他應(yīng)用。

有新的半透明 Activity(例如對(duì)話框)處于開(kāi)啟狀態(tài)。只要 Activity 仍然部分可見(jiàn)但并未處于焦點(diǎn)之中,它便會(huì)一直暫停。

當(dāng) Activity 進(jìn)入已暫停狀態(tài)時(shí),與 Activity 生命周期相關(guān)聯(lián)的所有生命周期感知型組件都將收到 ON_PAUSE 事件。這時(shí),生命周期組件可以停止在組件未位于前臺(tái)時(shí)無(wú)需運(yùn)行的任何功能,例如停止相機(jī)預(yù)覽。

您還可以使用 onPause() 方法釋放系統(tǒng)資源、傳感器(例如 GPS)手柄,或當(dāng)您的 Activity 暫停且用戶(hù)不需要它們時(shí)仍然可能影響電池續(xù)航時(shí)間的任何資源。然而,正如上文的 onResume() 部分所述,如果處于多窗口模式,“已暫停”的 Activity 仍完全可見(jiàn)。因此,您應(yīng)該考慮使用 onStop() 而非 onPause() 來(lái)完全釋放或調(diào)整與界面相關(guān)的資源和操作,以便更好地支持多窗口模式。

響應(yīng) ON_PAUSE 事件的以下 LifecycleObserver 示例與上述 ON_RESUME 事件示例相對(duì)應(yīng),會(huì)釋放在收到 ON_RESUME 事件后初始化的相機(jī):

Kotlin

class CameraComponent : LifecycleObserver {

...

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)

fun releaseCamera() {

camera?.release()

camera = null

}

...

}Java

public class JavaCameraComponent implements LifecycleObserver {

...

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)

public void releaseCamera() {

if (camera != null) {

camera.release();

camera = null;

}

}

...

}

請(qǐng)注意,上述代碼段在 LifecycleObserver 收到 ON_PAUSE 事件后放置相機(jī)釋放代碼。如前所述,請(qǐng)參閱使用生命周期感知型組件處理生命周期了解如何創(chuàng)建生命周期感知型組件。

不應(yīng)使用 onStop()。如需詳細(xì)了解如何保存數(shù)據(jù),請(qǐng)參閱保存和恢復(fù) Activity 狀態(tài)。

onStop()

如果您的 Activity 不再對(duì)用戶(hù)可見(jiàn),說(shuō)明其已進(jìn)入“已停止”狀態(tài),因此系統(tǒng)將調(diào)用 例如,當(dāng)新啟動(dòng)的 Activity 覆蓋整個(gè)屏幕時(shí),可能會(huì)發(fā)生這種情況。如果 Activity 已結(jié)束運(yùn)行并即將終止,系統(tǒng)還可以調(diào)用

當(dāng) Activity 進(jìn)入已停止?fàn)顟B(tài)時(shí),與 Activity 生命周期相關(guān)聯(lián)的所有生命周期感知型組件都將收到 ON_STOP 事件。這時(shí),生命周期組件可以停止在組件未顯示在屏幕上時(shí)無(wú)需運(yùn)行的任何功能。

您還應(yīng)使用

Kotlin

override fun onStop() {

// call the superclass method first

super.onStop()

// save the note's current draft, because the activity is stopping

// and we want to be sure the current note progress isn't lost.

val values = ContentValues().apply {

put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText())

put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle())

}

// do this update in background on an AsyncQueryHandler or equivalent

asyncQueryHandler.startUpdate(

token, // int token to correlate calls

null, // cookie, not used here

uri, // The URI for the note to update.

values, // The map of column names and new values to apply to them.

null, // No SELECT criteria are used.

null // No WHERE columns are used.

)

}Java

@Override

protected void onStop() {

// call the superclass method first

super.onStop();

// save the note's current draft, because the activity is stopping

// and we want to be sure the current note progress isn't lost.

ContentValues values = new ContentValues();

values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText());

values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle());

// do this update in background on an AsyncQueryHandler or equivalent

asyncQueryHandler.startUpdate (

mToken, // int token to correlate calls

null, // cookie, not used here

uri, // The URI for the note to update.

values, // The map of column names and new values to apply to them.

null, // No SELECT criteria are used.

null // No WHERE columns are used.

);

}

請(qǐng)注意,上述代碼示例直接使用 SQLite。但您應(yīng)該改用 Room,這是一個(gè)通過(guò) SQLite 提供抽象層的持久性庫(kù)。如需詳細(xì)了解使用 Room 的好處,以及如何在應(yīng)用中實(shí)現(xiàn) Room,請(qǐng)參閱 Room 持久性庫(kù)指南。

當(dāng)您的 Activity 進(jìn)入“已停止”狀態(tài)時(shí),

注意:Activity 停止后,如果系統(tǒng)需要恢復(fù)內(nèi)存,可能會(huì)銷(xiāo)毀包含該 Activity 的進(jìn)程。即使系統(tǒng)在 Activity 停止后銷(xiāo)毀相應(yīng)進(jìn)程,系統(tǒng)仍會(huì)保留 保存和恢復(fù) Activity 狀態(tài)。

進(jìn)入“已停止”狀態(tài)后,Activity 要么返回與用戶(hù)互動(dòng),要么結(jié)束運(yùn)行并消失。如果 Activity 返回,系統(tǒng)將調(diào)用

onDestroy()

銷(xiāo)毀 Ativity 之前,系統(tǒng)會(huì)先調(diào)用 onDestroy()。系統(tǒng)調(diào)用此回調(diào)的原因如下:Activity 即將結(jié)束(由于用戶(hù)徹底關(guān)閉 Activity 或由于系統(tǒng)為 Activity 調(diào)用 finish()),或者

由于配置變更(例如設(shè)備旋轉(zhuǎn)或多窗口模式),系統(tǒng)暫時(shí)銷(xiāo)毀 Activity

當(dāng) Activity 進(jìn)入已銷(xiāo)毀狀態(tài)時(shí),與 Activity 生命周期相關(guān)聯(lián)的所有生命周期感知型組件都將收到 ON_DESTROY 事件。這時(shí),生命周期組件可以在 Activity 被銷(xiāo)毀之前清理所需的任何數(shù)據(jù)。

您應(yīng)使用 ViewModel 對(duì)象來(lái)包含 Activity 的相關(guān)視圖數(shù)據(jù),而不是在您的 Activity 中加入邏輯來(lái)確定 Activity 被銷(xiāo)毀的原因。如果因配置變更而重新創(chuàng)建 Activity,ViewModel 不必執(zhí)行任何操作,因?yàn)橄到y(tǒng)將保留 ViewModel 并將其提供給下一個(gè) Activity 實(shí)例。如果不重新創(chuàng)建 Activity,ViewModel 將調(diào)用 onCleared() 方法,以便在 Activity 被銷(xiāo)毀前清除所需的任何數(shù)據(jù)。

您可以使用 isFinishing() 方法區(qū)分這兩種情況。

如果 Activity 即將結(jié)束,onDestroy() 是 Activity 收到的最后一個(gè)生命周期回調(diào)。如果由于配置變更而調(diào)用 onDestroy(),系統(tǒng)會(huì)立即新建 Activity 實(shí)例,然后在新配置中為新實(shí)例調(diào)用 onCreate()。

onDestroy() 回調(diào)應(yīng)釋放先前的回調(diào)(例如 onStop())尚未釋放的所有資源。

Activity 狀態(tài)和從內(nèi)存中彈出

系統(tǒng)會(huì)在需要釋放 RAM 時(shí)終止進(jìn)程;系統(tǒng)終止給定進(jìn)程的可能性取決于當(dāng)時(shí)進(jìn)程的狀態(tài)。反之,進(jìn)程狀態(tài)取決于在進(jìn)程中運(yùn)行的 Activity 的狀態(tài)。表 1 展示了進(jìn)程狀態(tài)、Activity 狀態(tài)以及系統(tǒng)終止進(jìn)程的可能性之間的關(guān)系。

系統(tǒng)終止進(jìn)程的可能性

進(jìn)程狀態(tài)

Activity 狀態(tài)

較小

前臺(tái)(擁有或即將獲得焦點(diǎn))

已創(chuàng)建

已開(kāi)始

已恢復(fù)

較大

后臺(tái)(失去焦點(diǎn))

已暫停

最大

后臺(tái)(不可見(jiàn))

已停止

已銷(xiāo)毀

表 1. 進(jìn)程生命周期和 Activity 狀態(tài)之間的關(guān)系

系統(tǒng)永遠(yuǎn)不會(huì)直接終止 Activity 以釋放內(nèi)存,而是會(huì)終止 Activity 所在的進(jìn)程。系統(tǒng)不僅會(huì)銷(xiāo)毀 Activity,還會(huì)銷(xiāo)毀在該進(jìn)程中運(yùn)行的所有其他內(nèi)容。如需了解如何在系統(tǒng)啟動(dòng)的進(jìn)程被終止時(shí)保留和恢復(fù) Activity 的界面狀態(tài),請(qǐng)參閱保存和恢復(fù) Activity 狀態(tài)。

用戶(hù)還可以使用“設(shè)置”下的“應(yīng)用管理器”來(lái)終止進(jìn)程,以終止相應(yīng)的應(yīng)用。

如需詳細(xì)了解一般進(jìn)程,請(qǐng)參閱進(jìn)程和線程。如需詳細(xì)了解進(jìn)程生命周期如何與其中 Activity 的狀態(tài)相關(guān)聯(lián),請(qǐng)參閱相應(yīng)頁(yè)面的進(jìn)程生命周期部分。

保存和恢復(fù)瞬時(shí)界面狀態(tài)

用戶(hù)期望 Activity 的界面狀態(tài)在整個(gè)配置變更(例如旋轉(zhuǎn)或切換到多窗口模式)期間保持不變。但是,默認(rèn)情況下,系統(tǒng)會(huì)在發(fā)生此類(lèi)配置更改時(shí)銷(xiāo)毀 Activity,從而清除存儲(chǔ)在 Activity 實(shí)例中的任何界面狀態(tài)。同樣,如果用戶(hù)暫時(shí)從您的應(yīng)用切換到其他應(yīng)用,并在稍后返回您的應(yīng)用,他們也希望界面狀態(tài)保持不變。但是,當(dāng)用戶(hù)離開(kāi)應(yīng)用且您的 Activity 停止時(shí),系統(tǒng)可能會(huì)銷(xiāo)毀該應(yīng)用的進(jìn)程。

當(dāng) Activity 因系統(tǒng)限制而被銷(xiāo)毀時(shí),您應(yīng)組合使用 ViewModel、onSaveInstanceState() 和/或本地存儲(chǔ)來(lái)保留用戶(hù)的瞬時(shí)界面狀態(tài)。如需詳細(xì)了解用戶(hù)期望與系統(tǒng)行為,以及如何在系統(tǒng)啟動(dòng)的 Activity 和進(jìn)程被終止后最大程度地保留復(fù)雜的界面狀態(tài)數(shù)據(jù),請(qǐng)參閱保存界面狀態(tài)。

本部分概述了實(shí)例狀態(tài)的定義,以及如何實(shí)現(xiàn) onSaveInstance() 方法,該方法是對(duì) Activity 本身的回調(diào)。如果界面數(shù)據(jù)簡(jiǎn)單且輕量,例如原始數(shù)據(jù)類(lèi)型或簡(jiǎn)單對(duì)象(比如 String),您可以單獨(dú)使用 onSaveInstanceState() 使界面狀態(tài)在配置更改和系統(tǒng)啟動(dòng)的進(jìn)程被終止時(shí)保持不變。但在大多數(shù)情況下,您應(yīng)使用 ViewModel 和 onSaveInstanceState()(如保存界面狀態(tài)中所述),因?yàn)?onSaveInstanceState() 會(huì)產(chǎn)生序列化/反序列化費(fèi)用。

實(shí)例狀態(tài)

在某些情況下,您的 Activity 會(huì)因正常的應(yīng)用行為而被銷(xiāo)毀,例如當(dāng)用戶(hù)按下返回按鈕或您的 Activity 通過(guò)調(diào)用 finish() 方法發(fā)出銷(xiāo)毀信號(hào)時(shí)。當(dāng)您的 Activity 因用戶(hù)按下返回按鈕或因其自行結(jié)束而被銷(xiāo)毀時(shí),系統(tǒng)和用戶(hù)對(duì)該 Activity 實(shí)例的概念將永遠(yuǎn)消失。在這些情況下,用戶(hù)的期望與系統(tǒng)行為相匹配,您無(wú)需完成任何額外工作。

但是,如果系統(tǒng)因系統(tǒng)限制(例如配置變更或內(nèi)存壓力)而銷(xiāo)毀 Activity,雖然實(shí)際的 Activity 實(shí)例會(huì)消失,但系統(tǒng)會(huì)記住它曾經(jīng)存在過(guò)。如果用戶(hù)嘗試回退到該 Activity,系統(tǒng)將使用一組描述 Activity 銷(xiāo)毀時(shí)狀態(tài)的已保存數(shù)據(jù)新建該 Activity 的實(shí)例。

系統(tǒng)用于恢復(fù)先前狀態(tài)的已保存數(shù)據(jù)稱(chēng)為實(shí)例狀態(tài),是存儲(chǔ)在 Bundle 對(duì)象中的鍵值對(duì)集合。默認(rèn)情況下,系統(tǒng)使用 Bundle 實(shí)例狀態(tài)來(lái)保存 Activity 布局中每個(gè) View 對(duì)象的相關(guān)信息(例如在 EditText 微件中輸入的文本值)。這樣,如果您的 Activity 實(shí)例被銷(xiāo)毀并重新創(chuàng)建,布局狀態(tài)便會(huì)恢復(fù)為其先前的狀態(tài),且您無(wú)需編寫(xiě)代碼。但是,您的 Activity 可能包含您要恢復(fù)的更多狀態(tài)信息,例如追蹤用戶(hù)在 Activity 中的進(jìn)程的成員變量。

注意:為了使 Android 系統(tǒng)恢復(fù) Activity 中視圖的狀態(tài),每個(gè)視圖必須具有 android:id 屬性提供的唯一 ID。

Bundle 對(duì)象并不適合保留大量數(shù)據(jù),因?yàn)樗枰谥骶€程上進(jìn)行序列化處理并占用系統(tǒng)進(jìn)程內(nèi)存。如需保存大量數(shù)據(jù),您應(yīng)組合使用持久性本地存儲(chǔ)、onSaveInstanceState() 方法和 ViewModel 類(lèi)來(lái)保存數(shù)據(jù),正如保存界面狀態(tài)中所述。

使用 onSaveInstanceState() 保存簡(jiǎn)單輕量的界面狀態(tài)

當(dāng)您的 Activity 開(kāi)始停止時(shí),系統(tǒng)會(huì)調(diào)用 onSaveInstanceState() 方法,以便您的 Activity 可以將狀態(tài)信息保存到實(shí)例狀態(tài) Bundle 中。此方法的默認(rèn)實(shí)現(xiàn)保存有關(guān) Activity 視圖層次結(jié)構(gòu)狀態(tài)的瞬時(shí)信息,例如 EditText 微件中的文本或 ListView 微件的滾動(dòng)位置。

如需保存 Activity 的其他實(shí)例狀態(tài)信息,您必須替換 onSaveInstanceState(),并將鍵值對(duì)添加到您的 Activity 意外銷(xiāo)毀時(shí)事件中所保存的 Bundle 對(duì)象中。替換 onSaveInstanceState() 時(shí),如果您希望默認(rèn)實(shí)現(xiàn)保存視圖層次結(jié)構(gòu)的狀態(tài),必須調(diào)用父類(lèi)實(shí)現(xiàn)。例如:

Kotlin

override fun onSaveInstanceState(outState: Bundle?) {

// Save the user's current game state

outState?.run {

putInt(STATE_SCORE, currentScore)

putInt(STATE_LEVEL, currentLevel)

}

// Always call the superclass so it can save the view hierarchy state

super.onSaveInstanceState(outState)

}

companion object {

val STATE_SCORE = "playerScore"

val STATE_LEVEL = "playerLevel"

}Java

static final String STATE_SCORE = "playerScore";

static final String STATE_LEVEL = "playerLevel";

// ...

@Override

public void onSaveInstanceState(Bundle savedInstanceState) {

// Save the user's current game state

savedInstanceState.putInt(STATE_SCORE, currentScore);

savedInstanceState.putInt(STATE_LEVEL, currentLevel);

// Always call the superclass so it can save the view hierarchy state

super.onSaveInstanceState(savedInstanceState);

}

注意:當(dāng)用戶(hù)顯式關(guān)閉 Activity 時(shí),或者在其他情況下調(diào)用 finish() 時(shí),系統(tǒng)不會(huì)調(diào)用 onSaveInstanceState()。

如需保存持久性數(shù)據(jù)(例如用戶(hù)首選項(xiàng)或數(shù)據(jù)庫(kù)中的數(shù)據(jù)),您應(yīng)在 Activity 位于前臺(tái)時(shí)抓住合適機(jī)會(huì)。如果沒(méi)有這樣的時(shí)機(jī),您應(yīng)在執(zhí)行 onStop() 方法期間保存此類(lèi)數(shù)據(jù)。

使用保存的實(shí)例狀態(tài)恢復(fù) Activity 界面狀態(tài)

重建先前被銷(xiāo)毀的 Activity 后,您可以從系統(tǒng)傳遞給 Activity 的 Bundle 中恢復(fù)保存的實(shí)例狀態(tài)。onCreate() 和 onRestoreInstanceState() 回調(diào)方法均會(huì)收到包含實(shí)例狀態(tài)信息的相同 Bundle。

因?yàn)闊o(wú)論系統(tǒng)是新建 Activity 實(shí)例還是重新創(chuàng)建之前的實(shí)例,都會(huì)調(diào)用 onCreate() 方法,所以在嘗試讀取之前,您必須檢查狀態(tài) Bundle 是否為 null。如果為 null,系統(tǒng)將新建 Activity 實(shí)例,而不會(huì)恢復(fù)之前銷(xiāo)毀的實(shí)例。

例如,以下代碼段顯示如何在 onCreate() 中恢復(fù)某些狀態(tài)數(shù)據(jù):

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState) // Always call the superclass first

// Check whether we're recreating a previously destroyed instance

if (savedInstanceState != null) {

with(savedInstanceState) {

// Restore value of members from saved state

currentScore = getInt(STATE_SCORE)

currentLevel = getInt(STATE_LEVEL)

}

} else {

// Probably initialize members with default values for a new instance

}

// ...

}Java

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState); // Always call the superclass first

// Check whether we're recreating a previously destroyed instance

if (savedInstanceState != null) {

// Restore value of members from saved state

currentScore = savedInstanceState.getInt(STATE_SCORE);

currentLevel = savedInstanceState.getInt(STATE_LEVEL);

} else {

// Probably initialize members with default values for a new instance

}

// ...

}

Kotlin

override fun onRestoreInstanceState(savedInstanceState: Bundle?) {

// Always call the superclass so it can restore the view hierarchy

super.onRestoreInstanceState(savedInstanceState)

// Restore state members from saved instance

savedInstanceState?.run {

currentScore = getInt(STATE_SCORE)

currentLevel = getInt(STATE_LEVEL)

}

}Java

public void onRestoreInstanceState(Bundle savedInstanceState) {

// Always call the superclass so it can restore the view hierarchy

super.onRestoreInstanceState(savedInstanceState);

// Restore state members from saved instance

currentScore = savedInstanceState.getInt(STATE_SCORE);

currentLevel = savedInstanceState.getInt(STATE_LEVEL);

}

注意:您應(yīng)始終調(diào)用 onRestoreInstanceState() 的父類(lèi)實(shí)現(xiàn),以便默認(rèn)實(shí)現(xiàn)可以恢復(fù)視圖層次結(jié)構(gòu)的狀態(tài)。

在 Activity 之間導(dǎo)航

在應(yīng)用的生命周期中,應(yīng)用很可能會(huì)多次進(jìn)入和退出 Activity。例如,用戶(hù)可以點(diǎn)按設(shè)備的返回按鈕,或者 Activity 可能需要啟動(dòng)不同的 Activity。本部分介紹了實(shí)現(xiàn)成功的 Activity 轉(zhuǎn)換需要了解的主題。這些主題包括從另一個(gè) Activity 啟動(dòng) Activity、保存 Activity 狀態(tài),以及恢復(fù) Activity 狀態(tài)。

從一個(gè) Activity 啟動(dòng)另一個(gè) Activity

Activity 通常需要在某個(gè)時(shí)刻啟動(dòng)另一個(gè) Activity。例如,當(dāng)應(yīng)用需要從當(dāng)前屏幕移動(dòng)到新屏幕時(shí),就會(huì)出現(xiàn)這種需求。

根據(jù)您的 Activity 是否希望從即將啟動(dòng)的新 Activity 中獲取返回結(jié)果,您可以使用

Intent 和 Intent 過(guò)濾器。

startActivity()

如果新啟動(dòng)的 Activity 不需要返回結(jié)果,當(dāng)前 Activity 可以通過(guò)調(diào)用

在自己的應(yīng)用中工作時(shí),您通常只需啟動(dòng)已知 Activity。例如,以下代碼段顯示如何啟動(dòng)一個(gè)名為 SignInActivity 的 Activity。

Kotlin

val intent = Intent(this, SignInActivity::class.java)

startActivity(intent)Java

Intent intent = new Intent(this, SignInActivity.class);

startActivity(intent);

您的應(yīng)用可能還希望使用 Activity 中的數(shù)據(jù)執(zhí)行某些操作,例如發(fā)送電子郵件、短信或狀態(tài)更新。在這種情況下,您的應(yīng)用自身可能不具有執(zhí)行此類(lèi)操作所需的 Activity,因此您可以改為利用設(shè)備上其他應(yīng)用提供的 Activity 為您執(zhí)行這些操作。這便是 intent 的真正價(jià)值所在。您可以創(chuàng)建一個(gè) intent,對(duì)您想執(zhí)行的操作進(jìn)行描述,系統(tǒng)會(huì)從其他應(yīng)用啟動(dòng)相應(yīng)的 Activity。如果有多個(gè) Activity 可以處理 intent,用戶(hù)可以選擇要使用哪一個(gè)。例如,如果您想允許用戶(hù)發(fā)送電子郵件,可以創(chuàng)建以下 intent:

Kotlin

val intent = Intent(Intent.ACTION_SEND).apply {

putExtra(Intent.EXTRA_EMAIL, recipientArray)

}

startActivity(intent)Java

Intent intent = new Intent(Intent.ACTION_SEND);

intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);

startActivity(intent);

添加到 intent 中的 EXTRA_EMAIL extra 是一個(gè)字符串?dāng)?shù)組,其中包含電子郵件的收件人電子郵件地址。當(dāng)電子郵件應(yīng)用響應(yīng)此 intent 時(shí),該應(yīng)用會(huì)讀取 extra 中提供的字符串?dāng)?shù)組,并將該數(shù)組放入電子郵件撰寫(xiě)表單的“收件人”字段。在這種情況下,電子郵件應(yīng)用的 Activity 會(huì)啟動(dòng),并且當(dāng)用戶(hù)完成操作時(shí),您的 Activity 會(huì)繼續(xù)運(yùn)行。

startActivityForResult()

有時(shí),您會(huì)希望在 Activity 結(jié)束時(shí)從 Activity 中獲取返回結(jié)果。例如,您可以啟動(dòng)一項(xiàng) Activity,讓用戶(hù)在聯(lián)系人列表中選擇收件人;當(dāng) Activity 結(jié)束時(shí),系統(tǒng)將返回用戶(hù)選擇的收件人。為此,您可以調(diào)用

當(dāng)子級(jí) Activity 退出時(shí),它可以調(diào)用 setResult(int) 將數(shù)據(jù)返回到其父級(jí)。子級(jí) Activity 必須始終提供結(jié)果代碼,該結(jié)果代碼可以是標(biāo)準(zhǔn)結(jié)果 RESULT_CANCELED、RESULT_OK,也可以是從 RESULT_FIRST_USER 開(kāi)始的任何自定義值。此外,子級(jí) Activity 可以根據(jù)需要返回包含它所需的任何其他數(shù)據(jù)的

如果子級(jí) Activity 由于任何原因(例如崩潰)而失敗,父級(jí) Activity 將收到代碼為 RESULT_CANCELED 的結(jié)果。

Kotlin

class MyActivity : Activity() {

// ...

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {

if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {

// When the user center presses, let them pick a contact.

startActivityForResult(

Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")),

PICK_CONTACT_REQUEST)

return true

}

return false

}

override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {

when (requestCode) {

PICK_CONTACT_REQUEST ->

if (resultCode == RESULT_OK) {

startActivity(Intent(Intent.ACTION_VIEW, intent?.data))

}

}

}

companion object {

internal val PICK_CONTACT_REQUEST = 0

}

}Java

public class MyActivity extends Activity {

// ...

static final int PICK_CONTACT_REQUEST = 0;

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {

// When the user center presses, let them pick a contact.

startActivityForResult(

new Intent(Intent.ACTION_PICK,

new Uri("content://contacts")),

PICK_CONTACT_REQUEST);

return true;

}

return false;

}

protected void onActivityResult(int requestCode, int resultCode,

Intent data) {

if (requestCode == PICK_CONTACT_REQUEST) {

if (resultCode == RESULT_OK) {

// A contact was picked. Here we will just display it

// to the user.

startActivity(new Intent(Intent.ACTION_VIEW, data));

}

}

}

}

協(xié)調(diào) Activity

當(dāng)一個(gè) Activity 啟動(dòng)另一個(gè) Activity 時(shí),它們都會(huì)經(jīng)歷生命周期轉(zhuǎn)換。第一個(gè) Activity 停止運(yùn)行并進(jìn)入“已暫?!被颉耙淹V埂睜顟B(tài),同時(shí)創(chuàng)建另一個(gè) Activity。如果這些 Activity 共享保存到磁盤(pán)或其他位置的數(shù)據(jù),必須要明確第一個(gè) Activity 在創(chuàng)建第二個(gè) Activity 之前并未完全停止。相反,啟動(dòng)第二個(gè) Activity 的過(guò)程與停止第一個(gè) Activity 的過(guò)程重疊。

生命周期回調(diào)的順序已有明確定義,特別是當(dāng)兩個(gè) Activity 在同一個(gè)進(jìn)程(應(yīng)用)中,并且其中一個(gè)要啟動(dòng)另一個(gè)時(shí)。以下是 Activity A 啟動(dòng) Activity B 時(shí)的操作發(fā)生順序:

Activity A 的

Activity B 的

然后,如果 Activity A 在屏幕上不再顯示,其

您可以利用這種可預(yù)測(cè)的生命周期回調(diào)順序管理從一個(gè) Activity 到另一個(gè) Activity 的信息轉(zhuǎn)換。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的android代理生命周期,了解 Activity 生命周期的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。