Android的Activity生命周期知識點總結,詳情

一. Activity生命周期

? ? 1.1?返回棧知識點

二. Activity狀態

? ? 2.1?啟動狀態

? ? 2.2?運行狀態

? ? 2.3?暫停狀態

? ? 2.4?停止狀態

? ? 2.5?銷毀狀態

三. Activity生存期

? ? 3.1?回調方法

? ? 3.2?生存期

四. 體驗Activity的生命周期

五. Activity被回收辦法

引言:

掌握Activity的生命周期對Android開發來說非常重要,當我們深入理解Activity的生命周期之后,就可以寫出更加連貫流暢的理序,并在如何合理管理應用資源方面發揮得游刃有余。我們的應用程序也將會擁有更好的用戶體驗。

.Activity生命周期

1.1返回棧:

我們知道,Android里的Activity可以層疊的,我們每啟動一個新的Activity,就會覆蓋在原來的Activity之上,然后點擊Back按鍵,會銷毀最上面的Activity,下面的一個Activity就會顯示出來。

其實Android是使用任務(task)來管理Activity的,一個任務就是一組存放在棧里的Activity的集合,這個棧也被稱作返回棧(back stack)。棧是一種后進先出的數據結構,在默認情況下,每當我們啟動了一個新的Activity,它就會在返回棧中入棧,并處于棧頂的位置。而每當我們按下Back鍵或調用finish()方法去銷毀一個Activity時,處于棧頂的Activity就會出棧,前一個入棧的Activity就會重新處于棧頂的位置。

系統總是會顯示處于棧頂的Activity給用戶。

1:返回棧流程圖

1.2 Activity狀態

Activity有主要的四個狀態,以及一個非常迅速的啟動狀態,下面我們來講解他們的功能:

1.2.1啟動狀態(Starting)

啟動狀態就是內個非常迅速的狀態,在Activity啟動時會自動跳轉到下一個狀態,這也就是為什么很多的Activity介紹里只寫了四個狀態而沒有介紹這個狀態了。

1.2.2運行狀態(Running)

當一個Activity位于返回棧的棧頂時,Activity就處于運行狀態。系統最不愿意回收的就是處于運行狀態的Activity,因為這會帶來非常差的運行體驗。

1.2.3暫停狀態(Paused)

當一個Activity不再處于棧頂的位置,但仍然可見時,Activity就進入了暫停狀態。你可能會覺得,既然Activity已經不在棧頂了,怎么會可見呢?這是因為并不是每一個Activity都會占滿整個屏幕,比如對話框式的Activity只會占用中間屏幕的部分區域。處于暫停狀態的Activity仍然是完全存活的,系統也不愿意回收這種Activity(因為它還是可見的,回收可見的東西都會在用戶體驗方面有不好的影響),只有在內存極低的情況下,系統才會去考慮回收這種Activity

1.2.4停止狀態(Stopped):

當一個Activity 不再處于棧頂位置,并且完全不可見的時候,就進人了停止狀態。系統仍然會為這種Activity保存相應的狀態和成員變量,但是這并不是完全可靠的,當其他地方需要內存時,處于停止狀態的Activity有可能會被系統回收。

1.2.5銷毀狀態(Destroyed):

一個Activity 從返回棧中移除后就變成了銷毀狀態。系統最傾向于回收處于這種狀態的Activity以保證手機的內存充足。

2 :狀態關系圖

1.3生存期

1.3.1回調方法

Activity類中定義了7個回調方法,其覆蓋了Activity生命周期的每一個環節,下面我們來一個一個看這 些方法:

1.onCreate()——創建

這個方法我們已經看到過很多次了,在每個Activity 中都重寫了這個方法,它會在Activity第一次被創建的時候調用。我們應該在這個方法中完成Activity的初始化操作,比如加載布局、綁定事件等。

2.onStart()——啟動

這個方法在Activity由不可見變為可見的時候調用

3.onResume()——恢復

這個方法在Activity準備好和用戶進行交互的時候調用。此時的Activity一定位于返回棧的棧頂,并且處于運行狀態。

4.onPause()——停頓

這個方法在系統準備去啟動或者恢復另一個Activity的時候調用。我們通常會在這個方法中將一些消耗CPU的資源釋放掉,以及保存一些關鍵數據,但這個方法的執行速度一定要快,不然會影響到新的棧頂Activity的使用。

5.onStop()——暫停

這個方法在Activity完全不可見的時候調用。它和onPause()方法的主要區別在于,如果啟動的新Activity是一個對話框式的Activity,那么onPause()方法會得到執行,而onstop()方法并不會執行。

6.onDestory()——銷毀

這個方法在Activity被銷毀之前調用,之后Activity的狀態將變為銷毀狀態。

7.onRestart——重啟

這個方法在Activity由停止狀態變為運行狀態之前調用,也就是Activity被重新啟動了。

1.3.2生存期

1.3.2.1完整生存期

完整生存期:Activity在onCreate()方法和onDestroy()方法之間所經歷的就是完整生存期。一般情況下, 一個Activity會在onCreate()方法中完成各種初始化操作,而在onDestroy()方法中完成釋放內存的操 作。

1.3.2.2可見生存期

ActivityonStart()方法和onStop()方法之間所經歷的就是可見生存期。在可見生存期內,Activity對于用戶總是可見的,即便有可能無法和用戶進行交互。我們可以通過這兩個方法合理地管理那些對用戶可見的資源。比如在onStart()方法中,對資源進行加載,而onStop()方法中對資源進行釋放,從而保證處于停止狀態的Activity不會占用過多內存。

1.3.2.3前臺生存期

ActivityonResume()方法和onPause()方法之間所經歷的就是前臺生存期。在前臺生存期內, Actvity總是處于運行狀態,此時的 Activity 是可以和用戶進行交互的,我們平時看到和接觸最多的就是這個狀態下的Activity。

3.Activity生命周期

1.4體驗Activity的生命周期

了解了Activity的生命周期之后,我們來寫一個實例,通過實例來詳細了解。

首先,我們新建一個EmptyActivity,名為NormalActivity,其布局起名為normal_layout;使用相同的方法創建DialogActivity,布局起名為dialog_layout

接下來,我們先編輯normal_layout.xml文件。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="match_ parent"

android:layout_height="match_ parent">

<Textview

android:Layout_width="match_parent"

android:layout_height="wrap_content

android:text="This is a normal activity"

/>

</LinearLayout>

在這里我們簡單的定義了一個TextView,顯示了一行文字"This is a normal activity"

接著我們編輯dialog_layout.xml文件,代碼如下:

<LinearLayout xmlns:android-"http://schemas.android.com/apk/res/android

android:orientation"vertical"

android: Layout_width="match_parent"

android: layout_height="match_parent">

<Textview

android:layout_width="match_parent"

android: layout_height="wrap_content"

android:text="This is a dialog activity"

/>

</LinearLayout>

接下來我們修改AndroidManifest.xml的標簽配件。

< activity
? ? ? ? ? ? ? ?android : name = ".DialogActivity"
? ? ? ? ? ? ? ?android : theme = "@style/Animation.Design.BottomSheetDialog" >
? ? ? ? </ activity >
< activity
? ? ? ? ? ? ? ?android : name = ".NormalActivity"
? ? ? ? ? ? ? ?android : exported = "false" />

這里注冊了兩個Activity,此時我們為什么使用了一個android:theme的屬性?這里是給前面的Activity指定主題,這里的"@style/Animation.Design.BottomSheetDialog"則毫無疑問是讓DialogActivity使用對話框的主題。現在,我們可以修改activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? ? ? ?android:orientation="vertical"

? ? ? ? ?android:layout_width="match_parent"

? ? ? ? ?android:layout_height="wrap_content">

? ? ? <Button

? ? ? ? ? ? ?android:layout_width="match_parent"

? ? ? ? ? ? ?android:layout_height="wrap_content"

? ? ? ? ? ? ?android:id="@+id/startNormalActivity"

? ? ? ? ? ? ?android:text="Start NormalActivity"/>

? ? ? ? ?<Button

? ? ? ? ? ? ? ? android:layout_width="match_parent"

? ? ? ? ? ? ? ? android:layout_height="wrap_content"

? ? ? ? ? ? ? ? android:id="@+id/startDialogActivity"

? ? ? ? ? ? ? ? android:text="Start DialogActivity"/>

</LinearLayout>

這里我們添加兩個按鈕,一個用于啟動NormalActivity,一個用于啟動DialogActivity,修改代碼:

import android.content.Intent;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";

@Override

protected void onCreate(Bundle savedInstanceState) {

? ? ? super.onCreate(savedInstanceState);

? ? ? Log.d(TAG, "onCreate");

? ? ? setContentView(R.layout.activity_main);

? ? ? findViewById(R.id.startNormalActivity).setOnClickListener(new

View.OnClickListener() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onClick(View v) {

? ? ? ? ? ? ? ? ? ?Intent intent = new Intent(MainActivity.this,

NormalActivity.class);

? ? ? ? ? ? ? ? ? ? ?startActivity(intent);

? ? ? ? ? ? ? ? ? ?}

? ? ? ? ? ? ?});

? ? ? ? ? ? ?findViewById(R.id.startDialogActivity).setOnClickListener(new

View.OnClickListener() {

? ? ? ? ? ? ? ? ?@Override

? ? ? ? ? ? ? ? ? public void onClick(View v) {

? ? ? ? ? ? ? ? ? ? ? ? ?Intent intent = new Intent(MainActivity.this,

? DialogActivity.class);

? ? ? ? ? ? ? ? ? ? ? ? ?startActivity(intent);

? ? ? ? ? ? ? ? ?}

? ? ? ? ? ?});

? }

? @Override

? protected void onStart() {

? ? ? ? ? super.onStart();

? ? ? ? ? Log.d(TAG, "onStart");

? }

? @Override

? protected void onResume() {

? ? ? ? ?super.onResume();

? ? ? ? ?Log.d(TAG, "onResume");

? }

? @Override

? protected void onPause() {

? ? ? ? ?super.onPause();

? ? ? ? ?Log.d(TAG, "onPause");

? }

? @Override

? protected void onStop() {

? ? ? ? ?super.onStop();

? ? ? ? ?Log.d(TAG, "onStop");

? }

? @Override

? protected void onDestroy() {

? ? ? ? super.onDestroy();

? ? ? ? Log.d(TAG, "onDestroy");

? }

}

現在,我們啟動程序,并看一下logcat的效果。

4Main界面圖

此時我們不對界面做任何操作,看log cat運行過程:

圖5:MainLogCat打印日志

這里其實我們就會發現,在MainActivity第一次被創建時會依次執行onCreateonStartonResume方法。

然后點擊第一個按鈕NormalActivity,打開normal_layout界面:

圖6:NormalActivity界面

此時的Logcat打印日志:

圖7:NormalActivity的LogCat打印日志

由于此時NormalActivity已經把MainActivity完全遮擋住,所以onPauseonStop都會執行。然后按下Back按鍵返回MainActivity

這時候我們返回原來的界面,再看log cat打印日志:

圖8:返回MainActivity時的打印日志

由于之前的MainActivity已經進入了停止狀態,所以onRestart方法會得到執行,之后會依次執行

onRestartonResume方法,此時onCreate方法不會執行,因為MainActivity并沒有重新創建。

點擊第二個按鈕,啟動DialogActivity

此時的logcat:

圖9:打開DialogActivity界面

可以看到,只有onPause的方法得到了執行,onStop沒有得到執行,這是因為DialogActivity并沒有完全遮擋住MainActivity,此時MainActivity只是進入暫停狀態,并沒有進入停止狀態。

最后在MainActivity按下Back按鍵,退出程序,打印程序:

圖10:結束界面

1.5Activity被回收辦法

前面講過,當一個Activity進入了停止狀態,是有可能被系統回收的。我們可以假設一種情況:有一個ActivityA,我們在這個基礎上啟動了ActivityB,這時候A任務就陷入停止狀態,這個時候由于系統的內存不足,系統將ActivityA回收掉了,然后用戶按下Back按鍵返回ActivityA,正常情況下還是會顯示ActivityA,這是并不會執行onRestart方法,而是會執行onCreate方法,因為A在這種情況下被重新創建一次。

但是偶爾我們還是回遇見一種情況,如果在A中可能會存在臨時數據和狀態,比如說A里有一個文本輸入框,我們輸入了一段數據;拿上面內個程序舉例,此時我們打開了NormalActivity,這時MainActivity由于內存不足被回收掉,此時我們如果點擊Back返回;此時如果內存不足的話,剛剛輸入的文字就都沒了,因為MainActivity被重建了。

這種情況是非常影響用戶體驗的,這時Activity里有一種回調方法我們就可以使用了——onSaveInstanceState(),這個方法可以保證在Activity被回收之前一定會被調用。

omSaveInstanceState()方法攜帶一個Bundle類的參數,Bundle提供一系列的方法用于保存數據,比如可以使用putString()方法保存字符串,使用putInt()方法保存整型數據,以此類推。每個保存方法需傳入兩個參數,第一個參數是鍵,用于后面的Bundle中取值,第二個參數是真正要保存到內容。

@Override

protected void onSaveInstanceState(Bundle outState) {

? ? ??super.onSaveInstanceState(outState);

? ? ? String tempData = "Something you just typed";

? ? ? outState.putString("data_key", tempData);

}

數據已經保存下來了,那么我們在哪里恢復呢?我們一直使用的onCreate方法其實也有一個Bundle類型的參數。這個參數在一般情況下都是null。但是如果在Activity被系統回收之前,我們通過 onSaveInstanceState方法保存數據,這個參數就會帶有之前的保存的數據,我們只需要通過相應的取值方法將數據去除,修改代碼如下:

import android.os.Bundle;

import android.util.Log;

import androidx.appcompat.app.AppCompatActivity;

public class MyActivity extends AppCompatActivity {

? ? ? private static final String TAG = "MyActivity"; // 確保你有一個合適的TAG?

? ? ? super.onCreate(savedInstanceState);

? ? ? Log.d(TAG, "onCreate");

? ? ? setContentView(R.layout.activity_main);

? ? ? if (savedInstanceState != null) {

? ? ? ? ? ??String tempData = savedInstanceState.getString("data_key");

? ? ? ? ? ? ?Log.d(TAG, "tempData is " + tempData);

? ? ? ? ?}

? ? ?}??

}

取出值之后再做相應的恢復操作就可以了。

我們會發現在使用Bundle保存和取出數據的時候和使用Intent傳遞 也有類似的方法。這里Intent還可以結合Bundle一起用于傳遞數據。

首先我們可以把傳遞的數據都保存在Bundle對象中,然后再將Bundle對象存放在Intent里,到了目標的Activity之后,先從Intent中取出Bundle,再從Bundle中一一取出數據。

注:另外,當手機的屏幕旋轉的時候,Activity也會有一個重建的過程,所以這時候,數據也可能發生丟失的情況。

?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/895616.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/895616.shtml
英文地址,請注明出處:http://en.pswp.cn/news/895616.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python----PyQt開發(PyQt基礎,環境搭建,Pycharm中PyQttools工具配置,第一個PyQt程序)

一、QT與PyQT的概念和特點 1.1、QT QT是一個1991年由The Qt Company開發的跨平臺C圖形用戶界面應用程序開發 框架&#xff0c;可構建高性能的桌面、移動及Web應用程序。也可用于開發非GUI程序&#xff0c;比如 控制臺工具和服務器。Qt是面向對象的框架&#xff0c;使用特殊的代…

win10 系統 自定義Ollama安裝路徑 及模型下載位置

win10 系統 自定義Ollama安裝路徑 及模型下載位置 由于Ollama的exe安裝軟件雙擊安裝的時候默認是在C盤&#xff0c;以及后續的模型數據下載也在C盤&#xff0c;導致會占用C盤空間&#xff0c;所以這里單獨寫了一個自定義安裝Ollama安裝目錄的教程。 Ollama官網地址&#xff1…

微軟官方出品GPT大模型編排工具:7個開源項目

今天一起盤點下&#xff0c;12月份推薦的7個.Net開源項目&#xff08;點擊標題查看詳情&#xff09;。 1、一個瀏覽器自動化操作的.Net開源庫 這是一個基于 Google 開源的 Node.js 庫 Puppeteer 的 .NET 開源庫&#xff0c;方便開發人員使用無頭 Web 瀏覽器抓取 Web、檢索 Ja…

蘋果CMS站群插件的自動生成功能:提升網站流量的秘訣

引言 在數字營銷的浪潮中&#xff0c;站群技術因其強大的流量引導能力而備受青睞。蘋果CMS作為一款優秀的內容管理系統&#xff0c;憑借其靈活性和可擴展性&#xff0c;成為了站群管理的理想選擇。本文將詳細介紹蘋果CMS站群插件的自動生成功能&#xff0c;探討如何通過這一功…

VS Code User和System版區別【推薦使用System版本】and VSCode+Keil協同開發之Keil Assistant

VS Code User和System版區別 Chapter1 VS Code User和System版區別1. 對于安裝而言2. 結束語 Chapter2 VS Code 安裝、配置教程及插件推薦插件&#xff1a; Chapter3 VSCodeKeil協同開發之Keil Assistant1. 效果展示2. Keil Assistant簡介3. Keil Assistant功能特性4. 部署步驟…

大語言模型入門

大語言模型入門 1 大語言模型步驟1.1 pre-training 預訓練1.1.1 從網上爬數據1.1.2 tokenization1.1.2.1 tokenization using byte pair encoding 1.3 預訓練1.3.1 context1.3.2 training1.3.3 輸出 1.2 post-training1&#xff1a;SFT監督微調1.2.1 token 1.3 強化學習1.3.1 基…

DeepSeek R1 本地部署和知識庫搭建

一、本地部署 DeepSeek-R1&#xff0c;是幻方量化旗下AI公司深度求索&#xff08;DeepSeek&#xff09;研發的推理模型 。DeepSeek-R1采用強化學習進行后訓練&#xff0c;旨在提升推理能力&#xff0c;尤其擅長數學、代碼和自然語言推理等復雜任務 。 使用DeepSeek R1, 可以大大…

基于大數據的全國熱門旅游景點數據分析系統的設計與實現

【大數據】基于大數據的全國熱門旅游景點數據分析系統的設計與實現&#xff08;完整系統源碼開發筆記詳細部署教程&#xff09;? 目錄 一、項目簡介二、項目界面展示三、項目視頻展示 一、項目簡介 該系統主要包括登錄注冊、系統首頁、圖表分析、數據管理和個人信息五大功能模…

李宏毅機器學習筆記:【6.Optimization、Adaptive Learning Rate】

Optimization 1.Adaptive Learning Rate2.不同的參數需要不同的學習率3.Root Mean Square4.RMSProp5.Adam6.learning rate scheduling7.warm up總結 critical point不一定是你在訓練一個network時候遇到的最大的障礙。 1.Adaptive Learning Rate 也就是我們要給每個參數不同的…

Task03:Ollama API 的使用

Ollama API 使用指南 簡介 Ollama 提供了強大的 REST API&#xff0c;使開發者能夠方便地與大語言模型進行交互。通過 Ollama API&#xff0c;用戶可以發送請求并接收模型生成的響應&#xff0c;應用于自然語言處理、文本生成等任務。本文將詳細介紹生成補全、對話生成的基本…

我用AI做數據分析之四種堆疊聚合模型的比較

我用AI做數據分析之四種堆疊聚合模型的比較 這里AI數據分析不僅僅是指AI生成代碼的能力&#xff0c;我想是測試AI數據分析方面的四個能力&#xff0c;理解人類指令的能力、撰寫代碼的能力、執行代碼的能力和解釋結果的能力。如果這四個能力都達到了相當的水準&#xff0c;才可…

DC-6靶機滲透測試全過程

目錄 前期準備 一、滲透測試 1.IP地址查詢 2.端口信息搜尋 3.網頁信息搜集 wappalyzer WPScan 反彈shell graham用戶 反彈出jens的shell nmap提權 二、總結 前期準備 攻擊機&#xff1a; kali windows11 靶機&#xff1a;DC-6靶機&#xff08;調至NAT模式&#xff0…

[操作系統] 基礎IO:系統文件I/O

在 Linux 操作系統中&#xff0c;文件 I/O&#xff08;輸入/輸出&#xff09;是程序與文件系統交互的基礎。理解文件 I/O 的工作原理對于編寫高效、可靠的程序至關重要。本文將深入探討系統文件 I/O 的機制。 一種傳遞標志位的方法 在 Linux 中&#xff0c;文件的打開操作通常…

3.8 AI驅動的市場調研革命:從數據采集到競品策略生成的閉環實踐指南

AI驅動的市場調研革命:從數據采集到競品策略生成的閉環實踐指南 引言:智能時代的高效市場洞察 Forrester研究顯示,使用AI輔助市場調研可使數據采集效率提升8倍,策略生成速度加快4倍。本文以GitHub Sentinel、LanguageMentor為案例,揭示如何構建AI增強型市場分析體系,實現…

AF3 MmcifObject類解讀

AlphaFold3 中 MmcifObject類 是 解析 mmCIF 文件的核心數據結構,用于存儲解析后的蛋白質結構信息,包含PDB 頭部信息、Biopython 解析的結構、鏈序列信息等。 下面代碼包含 Monomer 、AtomSite、ResiduePosition、ResidueAtPosition、 MmcifObject以及ParsingResult數據類的…

網絡安全 “免疫力”:從人體免疫系統看防御策略

在當今數字化時代&#xff0c;網絡安全已變得至關重要。每天&#xff0c;我們的網絡系統都面臨著來自各方的威脅&#xff0c;就像人體時刻暴露在各種病原體中一樣。今天&#xff0c;我們就來聊聊網絡安全與人體免疫系統的奇妙聯系&#xff0c;看看從免疫系統中能汲取哪些構建強…

滾動彈幕案例

滾動彈幕案例 一、需求 1.頁面上漂浮字體大小不一、顏色不一&#xff0c;從左向右滾動的彈幕&#xff1b; 2.底部中間有一個發送功能&#xff0c;可以發送新的彈幕&#xff1b; 3.底部的發送部分可以向下收起和彈出。 二、html <div class"container"><…

【wiki知識庫】08.添加用戶登錄功能--后端SpringBoot部分

目錄 一、今日目標? 二、SpringBoot后端實現 2.1 新增UserLoginParam 2.2 修改UserController 2.3 UserServiceImpl代碼 2.4 創建用戶上下文工具類 2.5?通過token校驗用戶&#xff08;重要&#xff09; 2.6 創建WebMvcConfig 2.7 用戶權限校驗攔截器 一、今日目標 上…

AI大模型的技術突破與傳媒行業變革

性能與成本&#xff1a;AI大模型的“雙輪驅動” 過去幾年&#xff0c;AI大模型的發展經歷了從實驗室到產業化的關鍵轉折。2025年初&#xff0c;以DeepSeek R1為代表的模型在數學推理、代碼生成等任務中表現超越國際頭部產品&#xff0c;而訓練成本僅為傳統模型的幾十分之一。這…

C++字符串處理指南:從基礎操作到性能優化——基于std::string的全面解析

博主將從C標準庫中的 std::string 出發&#xff0c;詳細探討字符串的處理方法&#xff0c;涵蓋常見操作、性能優化和實際應用場景。以下內容將圍繞std::string 的使用展開&#xff0c;結合代碼示例進行說明。 一、std::string 的基本操作 1.1 創建與初始化 std::string 提供了…