Skip to Content

Activity Lifecycle

1. Giới thiệu

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.

2. Sơ đồ Activity Lifecycle

UML Sequence Diagram

💡

Khi người dùng rời khỏi Activity, hệ thống gọi các methods để “tháo dỡ” Activity. Trong một số trường hợp, Activity chỉ bị tháo dỡ một phần và vẫn nằm trong bộ nhớ (khi chuyển sang app khác). Activity có thể quay lại foreground.

3. Các Lifecycle Callbacks

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.

onCreate()

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
⚠️

Activity không ở lại trạng thái Created. Sau khi onCreate() kết thúc, Activity chuyển sang trạng thái Started và hệ thống gọi onStart()onResume() ngay sau đó.

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

onStart()

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.

💡

Method onStart() hoàn thành nhanh chóng. Activity không ở lại trạng thái Started - ngay khi callback kết thúc, Activity chuyển sang trạng thái Resumed và gọi onResume().

onResume()

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
💡

Nếu Activity quay lại trạng thái Resumed từ Paused, hệ thống gọi lại onResume(). Vì vậy, implement onResume() để khởi tạo các components mà bạn release trong onPause().

onPause()

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
🚫

KHÔNG sử dụng onPause() để lưu dữ liệu app/user, network calls, hoặc database transactions. Những công việc này có thể không hoàn thành trước khi method kết thúc. Thay vào đó, thực hiện các heavy-load shutdown operations trong onStop().

onStop()

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)
💡

Sử dụng onStop() thay vì onPause() để các UI-related work tiếp tục, ngay cả khi người dùng xem Activity trong multi-window mode.

onDestroy()

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)
⚠️

Thay vì đặt logic trong Activity để xác định tại sao nó bị destroy, hãy sử dụng ViewModel để chứa view data. Nếu Activity được recreate do configuration change, ViewModel được bảo tồn và truyền cho Activity instance mới.

onRestart()

override fun onRestart() { super.onRestart() // Từ Stopped -> Started }

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

📌

Phân biệt restart và recreate:

  • Restart: Activity từ background quay lại foreground → onRestart() được gọi
  • Recreate: Configuration change (xoay màn hình) → Activity bị destroy và tạo mới → onRestart() KHÔNG được gọi

4. Ví dụ đầy đủ

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" } }

5. Các tình huống phổ biến

Mở Activity mới

Activity A: onPause() Activity B: onCreate() -> onStart() -> onResume() Activity A: onStop()

Nhấn Back từ B về A

Activity B: onPause() Activity A: onRestart() -> onStart() -> onResume() Activity B: onStop() -> onDestroy()

Xoay màn hình (Configuration Change)

onPause() -> onStop() -> onDestroy() onCreate() -> onStart() -> onResume()

Nhấn Home

onPause() -> onStop()

Quay lại từ Home

onRestart() -> onStart() -> onResume()

6. Lưu trữ và Khôi phục Instance State

Sử dụng onSaveInstanceState

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

// 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) }

rememberSaveable trong Compose

@Composable fun Counter() { var count by rememberSaveable { mutableStateOf(0) } Button(onClick = { count++ }) { Text("Count: $count") } }

7. ViewModel survive Configuration Change

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) } } }

8. Lifecycle với Compose

@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) } } }

9. Best Practices

// ✅ 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ế

📝 Tóm tắt

CallbackTrạng tháiKhi nàoViệc cần làm
onCreate()CreatedActivity được tạo lần đầuSetup UI, bind data, init ViewModel
onStart()StartedActivity hiển thịInit code duy trì UI
onResume()ResumedActivity interactiveStart camera, sensors
onPause()PausedActivity mất focusPause operations, release sensors
onStop()StoppedActivity không hiển thịSave data, heavy cleanup
onDestroy()DestroyedActivity bị hủyRelease all resources
onRestart()(transitional)Từ Stopped → StartedRefresh data nếu cần

📚 Tham khảo: Android Developers - Activity Lifecycle 

Last updated on