Vòng đời Activity trong Android: hiểu để tránh lỗi mất dữ liệu khi xoay màn hình

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Người dùng nghe điện thoại, xoay màn hình, chuyển sang ứng dụng khác rồi quay lại. Mỗi hành động đó đều tác động tới màn hình ứng dụng của bạn. Hiểu vòng đời Activity giúp bạn biết khi nào nên khởi tạo, lưu và giải phóng tài nguyên.

Activity là gì?

Activity đại diện cho một màn hình có giao diện mà người dùng tương tác. Hệ điều hành Android quản lý nó và gọi các phương thức vòng đời tại từng thời điểm. Bạn ghi đè những phương thức này để chạy mã đúng lúc.

Các phương thức vòng đời chính

Phương thứcKhi nào được gọiThường làm gì
onCreateActivity được tạoDựng giao diện, khởi tạo biến
onStartActivity sắp hiển thịChuẩn bị thứ cần cho giao diện
onResumeĐang ở phía trước, nhận tương tácBật cảm biến, camera, cập nhật
onPauseMất tiêu điểm, có thể còn nhìn thấyTạm dừng thứ nhạy cảm, lưu nhanh
onStopKhông còn hiển thịGiải phóng tài nguyên nặng
onDestroyBị hủyDọn dẹp cuối cùng
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.d("Lifecycle", "onCreate")
    }

    override fun onStart() {
        super.onStart()
        Log.d("Lifecycle", "onStart")
    }

    override fun onResume() {
        super.onResume()
        Log.d("Lifecycle", "onResume")
    }

    override fun onPause() {
        Log.d("Lifecycle", "onPause")
        super.onPause()
    }
}

Hãy thử in log như trên rồi xoay màn hình, bấm nút Home, mở lại ứng dụng. Quan sát thứ tự gọi là cách học nhanh nhất.

Vấn đề khi xoay màn hình

Mặc định, khi xoay màn hình hoặc đổi cấu hình (ngôn ngữ, chế độ tối), Android hủy rồi tạo lại Activity. Mọi biến trong Activity bị mất. Đó là lý do người mới hay thấy dữ liệu nhập dở biến mất sau khi xoay.

Giải pháp 1: onSaveInstanceState

Dùng cho lượng nhỏ dữ liệu giao diện, như vị trí cuộn hoặc nội dung ô nhập:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putInt("count", count)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    count = savedInstanceState?.getInt("count") ?: 0
}

Giải pháp 2: ViewModel

ViewModel sống lâu hơn Activity qua các lần xoay màn hình, là nơi thích hợp giữ dữ liệu và logic xử lý. Dữ liệu trong ViewModel không bị mất khi Activity bị tạo lại.

class CounterViewModel : ViewModel() {
    private val _count = MutableStateFlow(0)
    val count: StateFlow<Int> = _count

    fun increase() {
        _count.value++
    }
}

Lưu ý ViewModel không sống sót nếu hệ thống giết tiến trình khi thiếu bộ nhớ. Dữ liệu quan trọng cần lưu bền vững hoặc dùng SavedStateHandle.

Nguyên tắc thực hành tốt

  1. Không giữ tham chiếu tới Activity hoặc Context trong ViewModel hay đối tượng sống lâu, vì gây rò rỉ bộ nhớ.
  2. Đăng ký lắng nghe (cảm biến, vị trí) ở onStart hoặc onResume và hủy ở onStop hoặc onPause tương ứng.
  3. Không làm việc nặng trong onCreate hay onResume; chuyển sang luồng nền hoặc coroutine.
  4. Dùng thành phần nhận biết vòng đời (lifecycle-aware) như collect flow theo lifecycle để tự động dừng khi không hiển thị.
  5. Kiểm thử các tình huống: xoay màn hình, chia đôi màn hình, bật chế độ tiết kiệm bộ nhớ.

Những lỗi hay gặp

  • Gọi mạng lại mỗi lần xoay màn hình vì đặt trong onCreate mà không cache.
  • Quên hủy đăng ký nên ứng dụng chạy ngầm tốn pin.
  • Dùng biến toàn cục (static) để giữ dữ liệu giao diện, gây lỗi khó tìm.

Kết luận

Vòng đời là nền tảng của Android. Khi nhớ được thứ tự onCreate, onStart, onResume và cặp đối xứng khi rời đi, kết hợp với ViewModel, bạn sẽ tránh được hầu hết lỗi mất trạng thái. Dù dùng Compose thì các khái niệm này vẫn còn nguyên giá trị.

Các tình huống thực tế nên tự thử

Cách tốt nhất để nhớ vòng đời là tự gây ra từng tình huống và quan sát log. Thử mở ứng dụng rồi bấm nút Home: bạn thấy onPause rồi onStop. Mở lại từ danh sách ứng dụng gần đây: onRestart, onStart, onResume. Thử mở một hộp thoại hay Activity trong suốt phía trên: ứng dụng chỉ nhận onPause mà chưa bị onStop vì vẫn còn nhìn thấy. Thử bật chế độ chia đôi màn hình hoặc cuộc gọi đến để thấy hành vi mất tiêu điểm.

Một thử nghiệm quan trọng là bật tùy chọn nhà phát triển "Không giữ hoạt động" (Don't keep activities). Khi bật, hệ thống hủy Activity ngay khi bạn rời khỏi nó, mô phỏng tình huống thiếu bộ nhớ. Nếu ứng dụng của bạn vẫn khôi phục đúng trạng thái khi quay lại, bạn đã xử lý lưu trạng thái đúng cách. Đây là bài kiểm tra mà nhiều ứng dụng trượt nhưng rất ít người nhớ làm.

Nếu cần một lộ trình học Android có hệ thống, hãy xem các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment