onRestart — một phương thức trong vòng đời Activity của Android, được hệ thống gọi trước khi Activity trở về từ trạng thái Stopped sang trạng thái Started. onRestart báo hiệu rằng một Activity, trước đó bị ẩn bởi màn hình khác hoặc được thu nhỏ xuống nền, đang trở nên hiển thị lại cho người dùng. Trong onRestart, nhà phát triển cập nhật dữ liệu cũ, tải lại danh sách và khôi phục trạng thái UI có thể đã thay đổi trong khi Activity không hiển thị. Theo Google Android Vitals (2025), các ứng dụng sử dụng onRestart để cập nhật dữ liệu cho thấy 25% ít trường hợp hiển thị thông tin không chính xác hơn khi quay lại màn hình. Tài liệu Android Developers mô tả onRestart như một bước chuẩn bị trước khi Activity xuất hiện lại trên màn hình.
Những điểm chính
onRestart — một phương thức callback mà Android gọi ngay trước onStart khi một Activity trở về từ trạng thái Stopped không nhìn thấy thành trạng thái hiển thị. Phương thức này độc đáo ở chỗ nó chỉ được gọi khi Activity được hiển thị lại — trong lần tạo instance đầu tiên, trình tự bắt đầu bằng onCreate, bỏ qua onRestart. Vòng đời đầy đủ: onCreate → onStart → onResume (lần khởi chạy đầu tiên) hoặc onRestart → onStart → onResume (hiển thị sau đó).
Từ góc nhìn của hệ thống Android, onRestart là một sự tối ưu hóa cho phép Activity chuẩn bị cho việc quay trở lại: cập nhật dữ liệu từ kho lưu trữ, đồng bộ hóa trạng thái UI, kiểm tra kết nối mạng. Không giống như onResume, được gọi mỗi khi Activity nhận được tiêu điểm (bao gồm cả khi quay lại từ hộp thoại hoặc menu hệ thống), onRestart chỉ được kích hoạt trong một chu kỳ ẩn và trở về hoàn chỉnh. Điều này làm cho onRestart trở thành nơi lý tưởng cho các hoạt động cập nhật “nặng” không cần thiết trong quá trình mất tiêu điểm một phần.
Theo đặc tả vòng đời Activity của Android, khoảng thời gian giữa onStop và onRestart có thể từ vài giây (người dùng chuyển đổi nhanh) đến vài giờ (ứng dụng ở nền và người dùng quay lại). Trong thời gian này, dữ liệu trong nguồn từ xa (API, DB) có thể đã thay đổi, vì vậy onRestart là một điểm tự nhiên để kiểm tra tính cập nhật.
onRestart chỉ được gọi khi một Activity trở về từ trạng thái Stopped, trạng thái mà Activity đã nhập sau khi onStop được gọi. Dưới đây là tất cả các kịch bản dẫn đến onRestart.
Các kịch bản gọi onRestart:
Khi nào onRestart KHÔNG được gọi: trong quá trình xoay màn hình (Activity bị hủy và được tạo lại qua onCreate), khi quay lại từ hộp thoại (Activity không đi vào onStop, chỉ onPause → onResume), trong quá trình process death (Activity được tạo lại).
onRestart và onCreate là hai cách tiếp cận khác nhau để khôi phục một Activity. Sự lựa chọn giữa chúng phụ thuộc vào việc Activity đã bị hủy hoàn toàn hay chỉ bị ẩn.
| Đặc điểm | onRestart | onCreate |
|---|---|---|
| Khi nào được gọi | Activity trở về từ Stopped | Activity được tạo lần đầu hoặc sau khi bị hủy |
| Trạng thái được bảo toàn | Có — ViewModel và các trường còn sống | Không — mọi thứ được tạo mới |
| Bundle | Không được truyền | Được truyền (savedInstanceState) |
| Hành động điển hình | Cập nhật dữ liệu, làm mới UI | Khởi tạo View, đăng ký LiveData |
| Tần suất gọi | Mỗi lần quay lại | Một lần hoặc sau khi hủy |
Quy tắc lựa chọn: thực hiện khởi tạo View và đăng ký LiveData/StateFlow trong onCreate (hoặc onViewCreated cho Fragment). Cập nhật dữ liệu, tải lại danh sách và kiểm tra trạng thái — trong onRestart. Nếu dữ liệu được tải qua ViewModel, onRestart có thể chỉ cần gọi phương thức refresh() trên ViewModel, và View sẽ đăng ký dữ liệu đã cập nhật thông qua một luồng phản ứng.
Google khuyến nghị: không sao chép logic của onCreate trong onRestart. Trích xuất các phương thức refresh() trong ViewModel để tải dữ liệu hiện tại và gọi chúng trong onRestart. Điều này duy trì kiến trúc MVVM sạch sẽ và loại bỏ trùng lặp mã.
onRestart là nơi lý tưởng cho các hoạt động nên được thực hiện mỗi khi quay lại màn hình, nhưng không cần thiết khi mở lần đầu. Dưới đây là các kịch bản điển hình:
viewModel.refreshItems() trong onRestart.Những gì KHÔNG nên làm trong onRestart: không khởi tạo lại Views — chúng còn sống vì Activity không bị hủy. Không đăng ký lại LiveData — đăng ký trong onCreate vẫn còn hiệu lực. Không tạo Fragments mới — chúng đã có trong FragmentManager.
Ngoại lệ quan trọng nhất: onRestart không được gọi nếu tiến trình ứng dụng bị hệ thống tiêu diệt. Đây là điểm mấu chốt mà các nhà phát triển thường bỏ qua khi dựa vào onRestart để khôi phục trạng thái.
Trong quá trình process death:
Cách bảo vệ chống lại điều này: luôn lưu trạng thái quan trọng trong onSaveInstanceState(Bundle) (được gọi trước onStop) hoặc sử dụng SavedStateHandle trong ViewModel. Trong onCreate, kiểm tra savedInstanceState: nếu không phải null, khôi phục trạng thái từ Bundle; nếu là null, tải dữ liệu mới.
Theo Google Android Vitals, khoảng 7% số lần quay lại Activity sau thời gian dài ở nền xảy ra sau process death. Điều này có nghĩa là cứ 15 Activity lẽ ra phải gọi onRestart thì thực tế lại đi qua onCreate. Bỏ qua kịch bản này là một trong những nguyên nhân chính gây ra lỗi “màn hình trống sau khi quay lại”.
Activity gọi viewModel.refreshTasks() trong onRestart để cập nhật danh sách tác vụ sau khi quay lại từ màn hình chỉnh sửa.
class TaskListActivity : AppCompatActivity() {
private val viewModel: TaskViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_task_list)
viewModel.tasks.observe(this) { tasks ->
Log.d("TaskList", "Đã nhận ${tasks.size} tác vụ")
}
}
override fun onRestart() {
super.onRestart()
Log.d("TaskList", "onRestart: đang cập nhật danh sách tác vụ")
viewModel.refreshTasks()
}
}
class TaskViewModel : ViewModel() {
private val _tasks = MutableLiveData<List<Task>>()
val tasks: LiveData<List<Task>> get() = _tasks
fun refreshTasks() {
viewModelScope.launch {
_tasks.value = TaskRepository().getAllTasks()
}
}
}
ViewModel.refreshTasks() tải dữ liệu hiện tại từ kho lưu trữ. LiveData tự động thông báo cho Activity về các thay đổi dữ liệu — UI được cập nhật mà không cần mã bổ sung. onRestart không tạo đăng ký mới — nó đã được thiết lập trong onCreate.
Activity kiểm tra tính hợp lệ của mã thông báo khi quay lại và chuyển hướng đến đăng nhập nếu cần.
class ProfileActivity : AppCompatActivity() {
private val authManager = AuthManager()
private val launcher = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { Log.d("Profile", "Đã quay lại từ màn hình đăng nhập") }
override fun onRestart() {
super.onRestart()
if (!authManager.isTokenValid()) {
Log.d("Profile", "Mã thông báo hết hạn — đang chuyển hướng đến đăng nhập")
launcher.launch(Intent(this, LoginActivity::class.java))
}
}
}
class AuthManager {
fun isTokenValid(): Boolean {
val expiry = SharedPreferencesManager().getTokenExpiry()
return System.currentTimeMillis() < expiry
}
}
Nếu người dùng đã thu nhỏ ứng dụng trong thời gian dài và quay lại sau khi mã thông báo hết hạn, onRestart sẽ chuyển hướng họ đến màn hình đăng nhập. Điều này ngăn ngừa lỗi API khi cố gắng thực hiện yêu cầu với mã thông báo đã hết hạn. Lưu ý: việc kiểm tra nằm trong onRestart, không phải onResume, để tránh kiểm tra không cần thiết khi quay lại từ hộp thoại.
Fragment sử dụng onRestart qua LifecycleObserver để cập nhật dữ liệu.
class FeedFragment : Fragment() {
private val viewModel: FeedViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESTART)
fun onRestart() {
Log.d("FeedFragment", "onRestart qua LifecycleObserver")
viewModel.refreshFeed()
}
})
}
}
Thay vì ghi đè onRestart trong Fragment, LifecycleObserver được sử dụng — một cách tiếp cận linh hoạt hơn cho phép thêm logic sự kiện vòng đời mà không cần kế thừa. ViewLifecycleOwner đảm bảo rằng observer tồn tại trong phạm vi của View (nó không tồn tại lâu hơn onDestroyView).
Các câu hỏi thường gặp
onResume được gọi mỗi khi Activity nhận được tiêu điểm — bao gồm cả khi quay lại từ hộp thoại hoặc menu hệ thống (Activity không đi vào onStop). onRestart chỉ được gọi khi quay lại từ trạng thái Stopped, khi Activity bị ẩn hoàn toàn. onRestart là một sự kiện hẹp hơn cho các cập nhật “nặng”, trong khi onResume dành cho các hoạt động nhẹ (thay đổi tiêu đề, cập nhật thời gian).
Không, không thể. onRestart là một phương thức cặp với onStop: onRestart chỉ được gọi sau khi Activity đã đi qua onStop. Nếu Activity không đi vào onStop (ví dụ: một hộp thoại đã được mở), thì khi quay lại onRestart không được gọi — chỉ onResume.
Nhấn Home (nút trang chủ) trong trình giả lập — Activity sẽ thu nhỏ và nhận onStop. Sau đó mở ứng dụng qua Ứng dụng gần đây hoặc trình khởi chạy — Activity sẽ nhận onRestart → onStart → onResume. Để gỡ lỗi, sử dụng Debug với các điểm dừng trong onRestart hoặc Log.d với thẻ Activity.
Một ngoại lệ không được bắt trong onRestart sẽ gây ra Force Close. Hệ thống không bắt các ngoại lệ trong callback vòng đời. Nếu onRestart thực hiện các hoạt động có thể ném ngoại lệ (yêu cầu mạng không có try-catch, làm việc với View null), hãy bọc chúng trong try-catch.
Không. onRestart chỉ được gọi cho các Activity còn sống đang quay lại từ trạng thái Stopped. isFinishing() trong onRestart sẽ luôn là false. Kiểm tra isFinishing() có ý nghĩa trong onPause (lưu dữ liệu) và onDestroy (phân biệt tạo lại với kết thúc).
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm