Các sự kiện khác nhau (một số do người dùng kích hoạt và một số do hệ thống kích hoạt) có thể khiến Activity chuyển từ trạng thái này sang trạng thái khác. Tài liệu này mô tả một số trường hợp phổ biến mà trong đó các quá trình chuyển đổi như vậy xảy ra và cách xử lý những quá trình chuyển đổi đó.
Để biết thêm thông tin về trạng thái hoạt động, hãy xem phần Vòng đời hoạt động. Để tìm hiểu về cách lớp ViewModel có thể giúp bạn quản lý vòng đời hoạt động, hãy xem bài viết Tổng quan về ViewModel.
Đối với hầu hết các thay đổi về hoạt động, bạn không cần phản hồi trực tiếp các lệnh gọi lại trong vòng đời của activity. Vì Compose tạo lại giao diện người dùng từ trạng thái, nên bạn có thể tận dụng tính năng kết hợp lại tự động bằng cách đảm bảo rằng trạng thái được lưu trữ ở một vị trí thích hợp, chẳng hạn như rememberSaveable hoặc ViewModel.
Thay đổi cấu hình xảy ra
Có một số sự kiện có thể kích hoạt thay đổi cấu hình. Có lẽ ví dụ nổi bật nhất là thay đổi giữa hướng dọc và hướng ngang. Những trường hợp khác có thể gây ra thay đổi về cấu hình bao gồm thay đổi đối với chế độ cài đặt ngôn ngữ hoặc thiết bị đầu vào.
Khi có thay đổi về cấu hình, hoạt động sẽ bị huỷ bỏ và được tạo lại. Thao tác này sẽ kích hoạt các lệnh gọi lại sau đây trong thực thể hoạt động ban đầu:
Một thực thể mới của hoạt động sẽ được tạo và các lệnh gọi lại sau đây sẽ được kích hoạt:
Trong Compose, bạn thường không tương tác trực tiếp với các lệnh gọi lại này. Thay vào đó, hãy dùng Lifecycle API để ghi nhận các thay đổi về trạng thái. Trong Compose, bạn có thể dùng LocalLifecycleOwner.current để lấy vòng đời hiện tại và thêm một trình quan sát, cho phép bạn phản hồi các sự kiện.
Sử dụng kết hợp các thực thể ViewModel, rememberSaveable hoặc bộ nhớ liên tục cục bộ để duy trì trạng thái giao diện người dùng của một hoạt động khi có các thay đổi về cấu hình.
Việc quyết định cách kết hợp các lựa chọn này phụ thuộc vào độ phức tạp của dữ liệu giao diện người dùng, trường hợp sử dụng của ứng dụng và việc cân nhắc giữa tốc độ truy xuất so với mức sử dụng bộ nhớ. Đối với hầu hết các trường hợp sử dụng, bạn nên nâng trạng thái lên ViewModel và sử dụng rememberSaveable để đảm bảo trạng thái duy trì trong cả trường hợp thay đổi cấu hình và trường hợp bị buộc tắt do hệ thống gây ra. Để biết thêm thông tin về cách lưu trạng thái giao diện người dùng của hoạt động, hãy xem bài viết Lưu trạng thái giao diện người dùng.
Khi một hoạt động được tạo lại do thay đổi cấu hình, thành phần ban đầu sẽ bị loại bỏ. Việc sử dụng ViewModel hoặc rememberSaveable đảm bảo trạng thái giao diện người dùng của bạn được khôi phục trong thành phần mới.
Để biết thêm thông tin, hãy xem bài viết Vòng đời trong Jetpack Compose và Trạng thái và Jetpack Compose.
Xử lý các trường hợp nhiều cửa sổ
Khi một ứng dụng chuyển sang chế độ nhiều cửa sổ (có trong Android 7.0 (cấp độ API 24) trở lên), hệ thống sẽ thông báo cho hoạt động đang chạy về một thay đổi cấu hình, do đó, hoạt động sẽ trải qua các quá trình chuyển đổi vòng đời như mô tả trước đó.
Hành vi này cũng xảy ra nếu một ứng dụng đang ở chế độ nhiều cửa sổ bị đổi kích thước. Hoạt động của bạn có thể tự xử lý thay đổi về cấu hình hoặc có thể cho phép hệ thống hủy bỏ hoạt động và tạo lại hoạt động đó với các kích thước mới.
Để biết thêm thông tin về vòng đời chế độ nhiều cửa sổ, hãy xem phần giải thích về vòng đời chế độ nhiều cửa sổ trong bài viết Hỗ trợ chế độ nhiều cửa sổ.
Ở chế độ nhiều cửa sổ, mặc dù có 2 ứng dụng mà người dùng nhìn thấy, nhưng chỉ có ứng dụng mà người dùng đang tương tác mới ở nền trước và có tiêu điểm. Hoạt động đó ở trạng thái Đã tiếp tục, trong khi ứng dụng ở cửa sổ còn lại ở trạng thái Đã tạm dừng.
Khi người dùng chuyển từ ứng dụng A sang ứng dụng B, hệ thống sẽ gọi onPause trên ứng dụng A và onResume trên ứng dụng B. Phương thức này sẽ chuyển đổi giữa hai phương thức này mỗi khi người dùng chuyển đổi giữa các ứng dụng.
Để biết thêm thông tin chi tiết về chế độ nhiều cửa sổ, hãy tham khảo bài viết Hỗ trợ chế độ nhiều cửa sổ.
Hoạt động hoặc hộp thoại xuất hiện ở nền trước
Nếu một hoạt động hoặc hộp thoại mới xuất hiện ở nền trước, chiếm lấy tiêu điểm và che phủ một phần hoạt động đang diễn ra, thì hoạt động bị che phủ sẽ mất tiêu điểm và chuyển sang trạng thái Tạm dừng. Sau đó, hệ thống sẽ gọi onPause trên đối tượng đó.
Khi hoạt động bị che quay lại nền trước và lấy lại tiêu điểm, hệ thống sẽ gọi onResume.
Nếu một hoạt động hoặc hộp thoại mới xuất hiện ở nền trước, chiếm lấy tiêu điểm và che phủ hoàn toàn hoạt động đang diễn ra, thì hoạt động bị che phủ sẽ mất tiêu điểm và chuyển sang trạng thái Dừng. Sau đó, hệ thống sẽ gọi onPause và onStop một cách nhanh chóng.
Khi cùng một thực thể của hoạt động bị che khuất quay lại nền trước, hệ thống sẽ gọi onRestart, onStart và onResume trên hoạt động đó. Nếu đó là một phiên bản mới của hoạt động được che phủ chuyển sang nền, thì hệ thống sẽ không gọi onRestart, mà chỉ gọi onStart và onResume.
Quá trình kết hợp lại không bị ảnh hưởng bởi các hộp thoại xuất hiện ở nền trước. Tuy nhiên, các hiệu ứng phụ gắn liền với vòng đời, chẳng hạn như luồng và ảnh động, nên sử dụng các API nhận biết vòng đời (chẳng hạn như collectAsStateWithLifecycle) để tự động tạm dừng và tiếp tục công việc khi cần. Để biết thêm thông tin, hãy xem phần Trạng thái và Jetpack Compose.
Người dùng nhấn hoặc thực hiện cử chỉ Quay lại
Nếu một hoạt động ở nền trước và người dùng nhấn hoặc thực hiện cử chỉ Quay lại, thì hoạt động đó sẽ chuyển đổi thông qua các lệnh gọi lại onPause, onStop và onDestroy. Hoạt động bị huỷ và xoá khỏi ngăn xếp lui.
Trong một ứng dụng có một hoạt động (như hầu hết các ứng dụng Compose), rememberSaveable sẽ không duy trì trạng thái nếu thành phần kết hợp bị xoá khỏi ngăn xếp lui của hoạt động điều hướng. Nguyên nhân là do khi người dùng nhấn vào nút Quay lại, họ không mong đợi sẽ quay lại cùng một phiên bản, vì vậy, mọi trạng thái đều bị xoá.
Để triển khai hành vi tuỳ chỉnh cho nút Quay lại, chẳng hạn như hiển thị một hộp thoại yêu cầu người dùng xác nhận rằng họ muốn thoát ứng dụng của bạn, hãy sử dụng API NavigationEventHandler.
Hệ thống tắt quy trình ứng dụng
Nếu một ứng dụng đang chạy ở chế độ nền và hệ thống cần giải phóng bộ nhớ cho một ứng dụng trên nền trước, thì hệ thống có thể loại bỏ ứng dụng chạy ở chế độ nền đó. Khi hệ thống loại bỏ một ứng dụng, không có gì đảm bảo rằng onDestroy sẽ được gọi trong ứng dụng đó.
Để tìm hiểu thêm về cách hệ thống quyết định huỷ quy trình nào, hãy đọc bài viết Trạng thái của activity và việc loại bỏ khỏi bộ nhớ cũng như Quy trình và vòng đời ứng dụng.
Để tìm hiểu cách lưu trạng thái giao diện người dùng của hoạt động khi hệ thống huỷ quy trình ứng dụng của bạn, hãy xem bài viết Lưu và khôi phục trạng thái giao diện người dùng tạm thời.