Bỏ qua để đến nội dung

Lifecycle của Activity

Khi một Activity được khởi chạy, nó sẽ trải qua một loạt các bước từ khởi tạo đến hiển thị và cuối cùng bị hủy. Quá trình này được gọi là Activity Lifecycle (Vòng đời của Activity).

Activity class cung cấp một bộ 6 callbacks cốt lõi để điều hướng chuyển đổi giữa các giai đoạn:

  • onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy()

Hệ thống gọi mỗi callback này khi Activity chuyển sang trạng thái mới.

flowchart TB
Launched([Activity<br>launched])
onCreate["onCreate()"]
onStart["onStart()"]
onResume["onResume()"]
Running([Activity<br>running])
onPause["onPause()"]
onStop["onStop()"]
onDestroy["onDestroy()"]
Shutdown([Activity<br>shut down])
onRestart["onRestart()"]
Killed([App process<br>killed])
Launched --> onCreate
onCreate --> onStart
onStart --> onResume
onResume --> Running
Running --> |"Another activity comes<br>into the foreground"| onPause
onPause --> |"The activity is<br>no longer visible"| onStop
onStop --> |"The activity is finishing or<br>being destroyed by the system"| onDestroy
onDestroy --> Shutdown
onPause --> |"User returns<br>to the activity"| onResume
onStop --> |"User navigates<br>to the activity"| onRestart
onRestart --> onStart
onStop --> |"Apps with higher priority<br>need memory"| Killed
Killed -.-> |"User navigates<br>to the activity"| onCreate
style Launched fill:#8ecae6,stroke:#219ebc,stroke-width:2px,color:#000
style Running fill:#c5e063,stroke:#90a955,stroke-width:2px,color:#000
style Shutdown fill:#ffb703,stroke:#fb8500,stroke-width:2px,color:#000
style Killed fill:#ffb703,stroke:#fb8500,stroke-width:2px,color:#000
style onCreate fill:#e8e8e8,stroke:#999,stroke-width:1px
style onStart fill:#e8e8e8,stroke:#999,stroke-width:1px
style onResume fill:#e8e8e8,stroke:#999,stroke-width:1px
style onPause fill:#e8e8e8,stroke:#999,stroke-width:1px
style onStop fill:#e8e8e8,stroke:#999,stroke-width:1px
style onDestroy fill:#e8e8e8,stroke:#999,stroke-width:1px
style onRestart fill:#e8e8e8,stroke:#999,stroke-width:1px
sequenceDiagram
participant System
participant Activity
Note over System,Activity: Activity khởi chạy
System->>Activity: onCreate()
System->>Activity: onStart()
System->>Activity: onResume()
Note over Activity: Activity đang chạy
Note over System,Activity: User chuyển sang app khác
System->>Activity: onPause()
System->>Activity: onStop()
Note over System,Activity: User quay lại Activity
System->>Activity: onRestart()
System->>Activity: onStart()
System->>Activity: onResume()
Note over Activity: Activity đang chạy
Note over System,Activity: Activity bị đóng
System->>Activity: onPause()
System->>Activity: onStop()
System->>Activity: onDestroy()

Tùy thuộc vào độ phức tạp của Activity, bạn có thể không cần implement tất cả các lifecycle methods. Tuy nhiên, việc hiểu mỗi method rất quan trọng để app hoạt động đúng như người dùng mong đợi.

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Khôi phục instance state
gameState = savedInstanceState?.getString(GAME_STATE_KEY)
// Set layout cho activity
setContentView(R.layout.main_activity)
// Hoặc với Jetpack Compose
setContent {
MainScreen()
}
}

Bạn phải implement callback này. Nó được gọi khi hệ thống tạo Activity lần đầu. Khi Activity được tạo, nó chuyển sang trạng thái Created.

Những việc thường làm trong onCreate():

  • Thực hiện logic khởi tạo cơ bản chỉ xảy ra một lần trong suốt vòng đời
  • Bind data vào lists
  • Associate activity với ViewModel
  • Khởi tạo các class-scope variables

Về savedInstanceState parameter:

  • Là một Bundle object chứa trạng thái đã lưu trước đó của Activity
  • Nếu Activity chưa từng tồn tại trước đó, giá trị là null
override fun onStart() {
super.onStart()
// Activity hiển thị cho người dùng
// Khởi tạo code duy trì UI
}

Khi Activity chuyển sang trạng thái Started, hệ thống gọi onStart().

Callback này làm cho Activity hiển thị với người dùng khi app chuẩn bị để Activity vào foreground và trở nên tương tác. Đây là nơi code duy trì UI được khởi tạo.

override fun onResume() {
super.onResume()
// Activity ở foreground và tương tác với người dùng
// Khởi tạo camera, sensors, etc.
}

Khi Activity chuyển sang trạng thái Resumed, nó vào foreground và hệ thống gọi onResume(). Đây là trạng thái mà app tương tác với người dùng.

App ở lại trạng thái này cho đến khi có sự kiện khiến nó mất focus, ví dụ:

  • Nhận cuộc gọi điện thoại
  • Người dùng chuyển sang Activity khác
  • Màn hình tắt
override fun onPause() {
super.onPause()
// Tạm dừng hoặc điều chỉnh các operations
// Release system resources như GPS, sensors
}

Hệ thống gọi method này như dấu hiệu đầu tiên rằng người dùng đang rời khỏi Activity (không phải lúc nào cũng có nghĩa Activity bị destroy).

Các lý do Activity vào trạng thái Paused:

  • Có cuộc gọi điện thoại đến - màn hình cuộc gọi hiển thị đè lên app của bạn
  • Người dùng mở một dialog - ví dụ: dialog xin quyền (permission), dialog chọn ảnh, hoặc AlertDialog
  • Multi-window mode - khi màn hình chia đôi, chỉ app đang được chạm vào có focus, app còn lại ở trạng thái Paused
  • Activity bán trong suốt hiển thị - ví dụ: bottom sheet, popup menu, hoặc activity với theme trong suốt
override fun onStop() {
super.onStop()
// Activity không còn hiển thị
// Pause animations, lưu data vào database
}

Khi Activity không còn hiển thị cho người dùng, nó chuyển sang trạng thái Stopped và hệ thống gọi onStop().

Điều này xảy ra khi:

  • Activity mới được launch che toàn bộ màn hình
  • Activity hoàn thành chạy và sắp bị terminate

Những việc nên làm trong onStop():

  • Release hoặc điều chỉnh resources không cần thiết khi app không hiển thị
  • Pause animations
  • Chuyển từ fine-grained sang coarse-grained location updates
  • Lưu thông tin vào database (nếu không tìm được thời điểm tốt hơn)
override fun onDestroy() {
super.onDestroy()
// Release tất cả resources
// Cleanup final
}

onDestroy() được gọi trước khi Activity bị destroy. Hệ thống gọi callback này vì một trong hai lý do:

  1. Activity đang kết thúc (người dùng dismiss hoàn toàn hoặc finish() được gọi)
  2. Hệ thống tạm thời destroy Activity do configuration change (xoay màn hình, multi-window mode)
override fun onRestart() {
super.onRestart()
// Từ Stopped -> Started
}

Được gọi khi Activity restart từ trạng thái Stopped, ngay trước onStart().

class MainActivity : ComponentActivity() {
private var gameState: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Khôi phục instance state
gameState = savedInstanceState?.getString(GAME_STATE_KEY)
setContent {
MainScreen()
}
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart - Activity visible")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume - Activity interactive")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause - Activity losing focus")
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop - Activity not visible")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy - Activity destroyed")
}
override fun onRestart() {
super.onRestart()
Log.d(TAG, "onRestart - Activity restarting")
}
override fun onSaveInstanceState(outState: Bundle) {
outState.putString(GAME_STATE_KEY, gameState)
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
gameState = savedInstanceState.getString(GAME_STATE_KEY)
}
companion object {
private const val TAG = "MainActivity"
private const val GAME_STATE_KEY = "game_state"
}
}
Activity A: onPause()
Activity B: onCreate() -> onStart() -> onResume()
Activity A: onStop()
Activity B: onPause()
Activity A: onRestart() -> onStart() -> onResume()
Activity B: onStop() -> onDestroy()
onPause() -> onStop() -> onDestroy()
onCreate() -> onStart() -> onResume()
onPause() -> onStop()
onRestart() -> onStart() -> onResume()
override fun onSaveInstanceState(outState: Bundle) {
outState.putString(GAME_STATE_KEY, gameState)
outState.putInt(SCORE_KEY, score)
super.onSaveInstanceState(outState)
}

Khôi phục trong onCreate hoặc onRestoreInstanceState

Phần tiêu đề “Khôi phục trong onCreate hoặc onRestoreInstanceState”
// Cách 1: Trong onCreate
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gameState = savedInstanceState?.getString(GAME_STATE_KEY)
}
// Cách 2: Trong onRestoreInstanceState (chỉ gọi khi có saved state)
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
gameState = savedInstanceState.getString(GAME_STATE_KEY)
}
@Composable
fun Counter() {
var count by rememberSaveable { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("Count: $count")
}
}
class MainViewModel : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
// ViewModel survive configuration changes
// Data không bị mất khi xoay màn hình
override fun onCleared() {
super.onCleared()
// Cleanup khi ViewModel bị destroy
}
}
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val state by viewModel.uiState.collectAsState()
MainScreen(state)
}
}
}
@Composable
fun MyScreen() {
val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> {
Log.d("MyScreen", "Screen resumed")
}
Lifecycle.Event.ON_PAUSE -> {
Log.d("MyScreen", "Screen paused")
}
else -> {}
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
// ✅ Khởi tạo nhanh trong onCreate
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent { ... } // Chỉ setup UI
}
// ✅ Khởi tạo camera/sensors trong onResume
override fun onResume() {
super.onResume()
cameraManager.startPreview()
}
// ✅ Release resources trong onPause (cho resources cần release sớm)
override fun onPause() {
super.onPause()
cameraManager.stopPreview()
}
// ✅ Heavy operations trong onStop
override fun onStop() {
super.onStop()
saveDataToDatabase()
}
// ❌ Tránh heavy work trong onPause - có thể không hoàn thành
// ❌ Tránh network calls trong lifecycle callbacks
// Dùng ViewModel + Coroutines thay thế

Callback Trạng thái Khi nào Việc cần làm
onCreate() Created Activity được tạo lần đầu Setup UI, bind data, init ViewModel
onStart() Started Activity hiển thị Init code duy trì UI
onResume() Resumed Activity interactive Start camera, sensors
onPause() Paused Activity mất focus Pause operations, release sensors
onStop() Stopped Activity không hiển thị Save data, heavy cleanup
onDestroy() Destroyed Activity bị hủy Release all resources
onRestart() (transitional) Từ Stopped → Started Refresh data nếu cần

📚 Tham khảo: Android Developers - Activity Lifecycle