Android Activity全面解析:從創建到生命周期的完整指南

Activity作為Android四大組件之一,是構建用戶界面的核心單元。筆者通過郭霖著的第一行代碼入門安卓,內容基本都取自書中,這篇博客作為筆者的筆記同時精簡了一些書中內容分享在csdn中

一、Activity的創建與基礎配置

1.1 創建Activity的基本步驟

在Android項目中創建一個Activity需要遵循以下步驟:

  1. 定義Java類:新建一個繼承自Activity或其子類(如AppCompatActivity)的Java類
  2. 注冊到清單文件:在AndroidManifest.xml中聲明Activity,并配置必要的屬性(如launchMode
  3. 綁定布局:在onCreate()中調用setContentView(R.layout.xxx)加載界面布局
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main); // 綁定布局}
}

在實際開發中,Android Studio會自動完成大部分配置工作。我們只需在Java目錄下創建Activity,IDE會自動生成必要的XML配置。

1.2 Context的理解與應用

Activity繼承自Context類,這是一個抽象類,代表應用程序的環境信息,提供以下核心功能:

  • 訪問應用程序資源(如字符串、圖片等)
  • 啟動其他組件(Activity、Service等)
  • 獲取系統服務(如布局填充器、通知服務等)

在Activity內部使用this即可獲取Context對象,但在內部類中需要使用ActivityName.this來避免混淆。

1.3 Toast的合理使用

Toast用于向用戶顯示短暫的提示信息,會自動消失且不干擾用戶操作:

Button button = findViewById(R.id.button);
button.setOnClickListener(v -> {Toast.makeText(MainActivity.this, "操作成功", Toast.LENGTH_SHORT).show();
});

二、Activity的銷毀機制

2.1 finish()方法詳解

調用finish()方法會觸發Activity的銷毀流程:

  1. 生命周期回調順序:onPause()onStop()onDestroy()
  2. 系統最終會釋放資源并移除Activity實例

重要特性

  • finish()不會立即終止當前方法的執行,后續代碼仍會正常執行
  • 它只是標記Activity為待銷毀狀態,系統會在當前方法執行完畢后處理銷毀操作
  • 如果不調用finish(),Activity會保留在返回棧中,可能占用內存資源
button.setOnClickListener(v -> {finish(); // 標記銷毀Log.d("TEST", "這行代碼仍會執行"); // 正常輸出startActivity(new Intent(this, NextActivity.class));
});

2.2 銷毀場景分析

場景是否自動調用finish()備注
用戶按返回鍵系統默認處理
調用startActivity啟動新Activity舊Activity保留在棧中
配置變更(如旋轉屏幕)是(但會重建)系統自動處理
內存不足被系統回收不可預測

三、Activity間的切換與數據傳遞

1 顯式Intent切換Activity

顯式Intent明確指定要啟動的目標Activity類:

Intent intent = new Intent(CurrentActivity.this, TargetActivity.class);
startActivity(intent);

特點:

  • 明確知道要啟動哪個Activity
  • 代碼耦合性較高
  • 適用于應用內部跳轉

2 隱式Intent切換Activity

隱式Intent通過指定action、category等信息,由系統匹配合適的Activity:

<!-- AndroidManifest.xml中配置 -->
<activity android:name=".TargetActivity" android:exported="true"><intent-filter><action android:name="com.example.ACTION_TARGET"/><category android:name="android.intent.category.DEFAULT"/></intent-filter>
</activity>

還可以跳轉到網頁上,指定Intent的action為Intent.ACTION_VIEW,然后通過Uri.parse()方法將網址字符串解析成Uri對象,再調用Intent的setData方法將該Uri對象傳遞進去。

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.first_layout);Button bt1 = findViewById(R.id.button1);bt1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(MainActivity.this, "提醒一下", Toast.LENGTH_SHORT).show();finish();Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("https://www.quark.cn/s/JHK6vrGF1K12Y0Nl52?from=kkframenew_resultsearch&uc_param_str=ntnwvepffrbiprsvchutosstxs&by=submit&q=%E5%94%90%E4%BA%BA&queryId=h5FJGAyNpZHUOP9W0M9ypNrZ8Sxncku32B8QU6h4TDKLYwGehGZhZ35QkEgGGcqA0cWn4bVJAJDup1bvTQJ53ojFoMG12Bn1H11uPKOD0soRtrKZCUSFGJSGHK2sn"));startActivity(intent);}});

應用場景:

  • 啟動其他應用的Activity(如分享功能)
  • 實現應用內模塊解耦
  • 處理系統廣播和通知

傳遞數據

1.向下一個活動傳遞數據

Intent中提供了一系列putExtra()方法的重載,可以把向傳遞的數據暫存在Intent中,啟動另一個活動后只需要把數據再從Intent中取出就可以了。比如MainActivity中有一個字符串,想把字符串傳遞到SecondaryActivity中,運行如下代碼后可以在logcat中直接看到傳遞的Hello,world(xml文件中各加一個Button即可)。其中putExtra第一個參數相當于一個鍵,第二個參數是要傳遞的數據。

package com.example.myapplication;import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("MainActivity:", this.toString());setContentView(R.layout.first_layout);Button bt1 = findViewById(R.id.button1);bt1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String data = "Hello, world";Intent intent = new Intent(MainActivity.this, SecondaryActivity.class);intent.putExtra("main_data", data);startActivity(intent);}});}
}

接受數據的活動代碼中,先調用getIntent()得到該intent對象,然后用getStringExtra得到該數據。

package com.example.myapplication;import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.activity.EdgeToEdge;
import androidx.annotation.LongDef;
import androidx.appcompat.app.AppCompatActivity;public class SecondaryActivity extends AppCompatActivity {private static final String TAG = "SecondaryActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("SecondaryActivity:", this.toString());EdgeToEdge.enable(this);setContentView(R.layout.activity_secondary);Button button  = findViewById(R.id.btn2);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = getIntent();String data = intent.getStringExtra("main_data");Log.d("SecondaryActivity", data);}});}@Overrideprotected void onStop() {super.onStop();Log.d(TAG, "onStop: ");}@Overrideprotected void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy: ");}
}

2.返回數據給上一個活動

返回上一個活動只需要一個back鍵,并沒有啟動活動的intent來傳遞數據,但是Activity中有一個startActivityForResult()也是用來啟動活動的。該方法接收兩個參數,第一個參數是Intent,第二個參數是一個請求碼,用于在之后的回調中判斷數據來源.

package com.example.myapplication;import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("MainActivity:", this.toString());setContentView(R.layout.first_layout);Button bt1 = findViewById(R.id.button1);bt1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String data = "Hello, world";Intent intent = new Intent(MainActivity.this, SecondaryActivity.class);startActivityForResult(intent, 1);}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);switch (requestCode) {case 1:if (resultCode == RESULT_OK) {String returnedData = data.getStringExtra("data_return");Log.d( "First_Activity", returnedData);}break;default:}}
}

下面是另一個活動的代碼,我們還是構建一個Intent,但僅用來傳遞數據而不指定任何"意圖"切換活動,然后用setResult方法向上一個活動返回數據,接收兩個參數,第一個用于向上一個互動返回處理結果,一般使用RESULT_OKRESULT_CANCELD兩個值,第二個則把帶有數據的Intent傳遞回去,然后用finish銷毀該活動以返回上一個活動。由于使用startActivityForResult啟動活動,,在第二個活動被銷毀后會回調上一個活動的onActivityResult()方法,因此需要重寫第一個活動中這個方法得到返回的數據。該方法有三個參數,第一個參數resultCode,即傳入的請求碼,第二個參數resultCode是返回的處理結果,第三個參數data即攜帶返回數據的Intent

package com.example.myapplication;import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import androidx.activity.EdgeToEdge;
import androidx.annotation.LongDef;
import androidx.appcompat.app.AppCompatActivity;public class SecondaryActivity extends AppCompatActivity {private static final String TAG = "SecondaryActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);Log.d("SecondaryActivity:", this.toString());EdgeToEdge.enable(this);setContentView(R.layout.activity_secondary);Button button  = findViewById(R.id.btn2);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.putExtra("data_return", "Hello, world");setResult(RESULT_OK, intent);finish();}});}@Overrideprotected void onStop() {super.onStop();Log.d(TAG, "onStop: ");}@Overrideprotected void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy: ");}
}

四、Activity的生命周期管理

4.1 Activity的四種狀態

  1. 運行狀態(Active/Running)

    • 位于棧頂,可見且可交互
    • 系統最不可能回收的狀態
  2. 暫停狀態(Paused)

    • 不再處于棧頂但仍部分可見
    • 如被對話框式Activity覆蓋時
    • 系統可能在內存緊張時回收
  3. 停止狀態(Stopped)

    • 完全不可見
    • 仍保留狀態和成員變量
    • 系統可能回收內存
  4. 銷毀狀態(Destroyed)

    • 被系統回收或調用finish()
    • 需要重建才能再次使用

4.2 生命周期回調方法

Activity類定義了7個核心回調方法:

  1. onCreate()

    • 首次創建時調用
    • 完成初始化(加載布局、綁定數據等)
    • 必須調用super.onCreate()
  2. onStart()

    • 由不可見變為可見時調用
    • 適合啟動動畫、注冊監聽器等
  3. onResume()

    • 進入可交互狀態
    • 恢復暫停時被停止的功能(如相機)
  4. onPause()

    • 失去焦點,部分可見
    • 必須快速執行(不能做耗時操作)
    • 保存持久性數據
  5. onStop()

    • 完全不可見
    • 適合釋放不必要資源
  6. onDestroy()

    • 被銷毀前調用
    • 釋放所有資源,避免內存泄漏
  7. onRestart()

    • 由停止狀態重新啟動時調用
    • 后接onStart()

4.3 生命周期場景分析

啟動Activity: onCreate -> onStart -> onResume
按下Home鍵: onPause -> onStop
返回應用: onRestart -> onStart -> onResume
回退退出: onPause -> onStop -> onDestroy

對話框式Activity的影響

  • 只會觸發onPause(),不會觸發onStop()
  • 底層Activity仍部分可見

五、Activity的啟動模式

AndroidManifest.xml中通過android:launchMode屬性配置:

5.1 standard(標準模式)

  • 默認模式
  • 每次啟動都創建新實例
  • 允許多個相同Activity實例存在
  • 典型的棧內管理方式
<activity android:name=".StandardActivity" android:launchMode="standard"/>

5.2 singleTop(棧頂復用)

  • 如果目標Activity已在棧頂,則復用實例
  • 避免重復創建相同Activity
  • 適用于通知跳轉等場景
<activity android:name=".SingleTopActivity"android:launchMode="singleTop"/>

5.3 singleTask(棧內復用)

  • 整個任務棧中只存在一個實例
  • 如果已存在,則清除其上的所有Activity
  • 適合應用的主頁Activity
<activity android:name=".MainActivity"android:launchMode="singleTask"/>

5.4 singleInstance(單例模式)

  • 啟用獨立的返回棧管理
  • 保證只有一個實例存在
  • 多個應用共享同一個Activity實例
  • 適合鬧鐘等系統級功能
<activity android:name=".AlarmActivity"android:launchMode="singleInstance"/>

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

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

相關文章

深入理解 Python 的 secrets 模塊:打造更安全的隨機數生成機制

深入理解 Python 的 secrets 模塊&#xff1a;打造更安全的隨機數生成機制 在構建涉及用戶身份認證、權限管理、加密通信等系統時&#xff0c;開發者最不能忽視的一個問題就是“安全性”。安全問題的核心之一在于“隨機性”——尤其是密碼、驗證碼、Token、Session、API Key 的…

CHAPTER 19 Concurrency Models in Python

一、A Bit of Jargon 1、關鍵術語解析 1.1 并發 (Concurrency) 定義: 并發是指同時處理多個待處理任務的能力&#xff0c;這些任務可以依次或并行&#xff08;如果可能&#xff09;進行&#xff0c;最終每個任務都會成功或失敗。 理解: 單核 CPU: 即使是單核 CPU 也可以實…

DCM4CHEE Archive Light 開發環境部署(5)-IDEA集成調試配置

系列文章目錄 DCM4CHEE Archive light 開發環境部署(1)-前言DCM4CHEE Archive light 開發環境部署(2)-PostgreSQLDCM4CHEE Archive light 開發環境部署(3)-OpenLDAPDCM4CHEE Archive light 開發環境部署(4)-Wildfly(JBoss)DCM4CHEE Archive light 開發環境部署(5)-IDEA集成…

在rust中執行命令行輸出中文亂碼解決辦法

如果你使用標準的依賴庫執行命令中包含中文的話&#xff0c; 就會發現中文亂碼&#xff0c;如果你的輸出中沒有中文&#xff0c;就可以正常輸出&#xff0c;因為windows的命令行默認使用的是gbk編碼。。。。。 #[tauri::command] pub async fn run_command(command: String) -…

判斷當前瀏覽器卡不卡

方法一&#xff1a;使用 requestAnimationFrame 和時間戳計算平均 FPS let frameCount 0; let lastTime performance.now(); let fps 0; let isSlow false; // 是否卡頓的標志function calculateFPS(currentTime) {frameCount;// 每隔大約 1000 毫秒&#xff08;1秒&#…

51c嵌入式~電路~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/11748634 一、延長電子元器件的貨架壽命 本文探討了電子元器件的貨架壽命問題&#xff0c;重點討論了氧化、濕度敏感等級&#xff08;MSL&#xff09;與貨架壽命之間的關系。文章通過具體例子說明了氧化對電子元器件可…

Eureka 與 Feign(一)

Eureka 與 Feign 知識解析 1. Eureka Spring Cloud Eureka 是服務發現組件&#xff0c;包含&#xff1a; Eureka Server&#xff1a;注冊中心&#xff0c;管理服務實例Eureka Client&#xff1a;服務實例&#xff0c;向注冊中心注冊/獲取服務信息 核心功能&#xff1a; 服…

AN動畫軟件|Animate 2025百度云下載與安裝教程指南

如大家所了解的&#xff0c;?Animate全稱Adobe Animate&#xff0c;常常也被簡稱為AN。它是一款2D動畫制作軟件?&#xff0c;其前身為Flash Professional CC&#xff0c;2016年更名為Animate CC&#xff0c;支持Flash SWF文件及HTML5動畫創作&#xff0c;廣泛應用于網頁交互、…

提示詞工程中常見協議框架應用實例

一、生成式診斷催化協議(Generative Diagnosis Catalysis, GDC) 技術原理:基于神經符號系統的因果推理引擎,融合貝葉斯網絡與強化學習 實施場景: class DiagnosticCatalyst:def __init__(self, domain="醫療診斷"):self.causal_graph

資深Java工程師的面試題目(七)JDK JVM

以下是針對 Java 面試者 的 JVM 和 JDK 相關題目&#xff0c;涵蓋核心知識點、實際應用場景和進階問題&#xff1a; 一、JVM 基礎 1. JVM 內存模型 題目&#xff1a; 請描述 JVM 的內存模型及其組成部分&#xff0c;并說明每個區域的作用。 解析&#xff1a; JVM 內存模型分…

【系統設計【4】】設計一個限流器:從理論到實踐的完整解決方案

文章目錄 第一步&#xff1a;理解問題并確定設計范圍1、為什么需要限流器2、需求澄清的藝術3、需求總結與優先級 第二步&#xff1a;提出高層次設計并獲得認同1. 限流器的部署位置選擇2. 限流算法的選擇與權衡3. 高層架構設計 第三步&#xff1a;深入設計1、限流規則的設計與管…

基于DETR目標檢測項目

DETR見解 DETR&#xff08;Detection Transformer&#xff09;是一種端到端的目標檢測模型&#xff0c;由Facebook AI Research&#xff08;FAIR&#xff09;于2020年提出。DETR采用了Transformer架構&#xff0c;與傳統的基于區域的目標檢測方法有所不同&#xff0c;它通過全…

ZooKeeper 集群部署

ZooKeeper 集群部署 前言安裝部署資源下載JDK 部署Zookeeper 部署 前言 在 Linux 服務器上部署 Zookeeper 之前&#xff0c;需要先安裝 JDK。以下是相關版本及環境信息&#xff1a; JDK 版本 jdk-17_linux-x64_bin.tar.gz Zookeeper 部署的版本 3.5.7 操作系統版本 Red Hat E…

8.TCP Server端實現

1.C/S模型 2.Server 端功能分析 tcp_server.c #include "tcp_server.h" #include "lwip/sockets.h" #include <stdio.h>char ReadBuff[BUFF_SIZE]; /* TCP服務器任務函數 */ void vTcpserver_Task(void) {int sfd, cfd, n, i;struct sockaddr_in…

課設作業圖書管理系統

用戶注冊&#xff0c;登錄 播放地址 課設作業圖書管理系統_嗶哩嗶哩_bilibili 對圖書進行增刪改查 package com.xwr.controller; import com.xwr.entity.Book; import com.xwr.entity.Category; import com.xwr.service.BookService; import com.xwr.service.CategoryServ…

springboot 配置加密

springboot 配置加密 [TOC](springboot 配置加密) 前言一、在配置類賦值之前解密二、修改賦值后加密的配置類 前言 在一些國家項目中經常會要求不能暴露數據庫鏈接和密碼, 所以需要對配置文件里面的一些配置進行加密處理。 解決方法有兩種&#xff1a;一種是在配置加載后還沒給…

【操作系統】macOS軟件提示“已損壞,打不開”的解決方案

macOS軟件提示“已損壞&#xff0c;打不開”的解決方案 在使用 macOS 系統時&#xff0c;不少用戶都遇到過這樣的情況&#xff1a;當嘗試打開某個應用程序時&#xff0c;系統彈出提示“xxx 已損壞&#xff0c;打不開。您應該將它移到廢紙簍”&#xff0c;或者顯示“無法打開‘…

數據庫系統概論(二十)數據庫恢復技術

數據庫系統概論&#xff08;二十&#xff09;數據庫恢復技術 前言一、事務的基本概念1. 什么是事務&#xff1f;2. 事務的兩種"打開方式"2.1 隱式事務2.2 顯式事務&#xff1a;自己動手打包操作 3. 事務的四大"鐵律3.1 原子性3.2 一致性3.3 隔離性3.4 持久性 4.…

java將pdf文件轉換為圖片工具類

一、相關依賴 <!-- PDFBox for PDF processing --><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.27</version></dependency>二、工具類 import org.apache.pdfbox.p…

零門檻探索國產數據庫硬核實力 —— 金倉數據庫在線體驗平臺體驗記

1、 金倉數據庫在線體驗平臺 最近&#xff0c;我發現了一個超棒的數據庫寶藏 —— 金倉數據庫在線體驗平臺。它在金倉社區上線后&#xff0c;憑借 “零門檻體驗 多場景交互” 的特點&#xff0c;迅速吸引了眾多數據庫愛好者的目光&#xff0c;我也忍不住去體驗了一番。 2、 …