Activity作為Android四大組件之一,是構建用戶界面的核心單元。筆者通過郭霖著的
第一行代碼
入門安卓,內容基本都取自書中,這篇博客作為筆者的筆記同時精簡了一些書中內容分享在csdn中
一、Activity的創建與基礎配置
1.1 創建Activity的基本步驟
在Android項目中創建一個Activity需要遵循以下步驟:
- 定義Java類:新建一個繼承自
Activity
或其子類(如AppCompatActivity
)的Java類 - 注冊到清單文件:在
AndroidManifest.xml
中聲明Activity,并配置必要的屬性(如launchMode
) - 綁定布局:在
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的銷毀流程:
- 生命周期回調順序:
onPause()
→onStop()
→onDestroy()
- 系統最終會釋放資源并移除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_OK
和RESULT_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的四種狀態
-
運行狀態(Active/Running):
- 位于棧頂,可見且可交互
- 系統最不可能回收的狀態
-
暫停狀態(Paused):
- 不再處于棧頂但仍部分可見
- 如被對話框式Activity覆蓋時
- 系統可能在內存緊張時回收
-
停止狀態(Stopped):
- 完全不可見
- 仍保留狀態和成員變量
- 系統可能回收內存
-
銷毀狀態(Destroyed):
- 被系統回收或調用finish()
- 需要重建才能再次使用
4.2 生命周期回調方法
Activity類定義了7個核心回調方法:
-
onCreate()
:- 首次創建時調用
- 完成初始化(加載布局、綁定數據等)
- 必須調用
super.onCreate()
-
onStart()
:- 由不可見變為可見時調用
- 適合啟動動畫、注冊監聽器等
-
onResume()
:- 進入可交互狀態
- 恢復暫停時被停止的功能(如相機)
-
onPause()
:- 失去焦點,部分可見
- 必須快速執行(不能做耗時操作)
- 保存持久性數據
-
onStop()
:- 完全不可見
- 適合釋放不必要資源
-
onDestroy()
:- 被銷毀前調用
- 釋放所有資源,避免內存泄漏
-
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"/>