Câu hỏi phỏng vấn Activity/Fragment Lifecycle
Phần này tổng hợp các câu hỏi về Lifecycle - một trong những khái niệm quan trọng nhất của Android development.
1. Activity Lifecycle
Q: Giải thích chi tiết Activity Lifecycle?
Trả lời:
Activity Lifecycle gồm 7 callback methods chính:
| Callback | Mô tả | Actions |
|---|---|---|
onCreate() | Activity được tạo lần đầu | Setup UI, bind data, initialize |
onStart() | Activity visible cho user | Start animations |
onResume() | Activity foreground, interactive | Resume video/audio, refresh UI |
onPause() | Losing focus, still visible | Pause video/audio, save lightweight state |
onStop() | Not visible | Release resources, stop updates |
onRestart() | From stopped → started | Refresh data if needed |
onDestroy() | Being destroyed | Cleanup, unregister listeners |
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Timber.d("onCreate - Initialize UI")
}
override fun onStart() {
super.onStart()
Timber.d("onStart - Activity visible")
}
override fun onResume() {
super.onResume()
Timber.d("onResume - Activity interactive")
}
override fun onPause() {
super.onPause()
Timber.d("onPause - Saving lightweight state")
}
override fun onStop() {
super.onStop()
Timber.d("onStop - Releasing resources")
}
override fun onDestroy() {
super.onDestroy()
Timber.d("onDestroy - Cleanup")
}
}📚 Tìm hiểu thêm: Activity Lifecycle
Q: onSaveInstanceState() vs onRestoreInstanceState()?
Trả lời:
Dùng để lưu và khôi phục UI state khi Activity bị destroy (configuration change, system kill).
// Lưu state
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putString("search_query", searchEditText.text.toString())
outState.putInt("scroll_position", recyclerView.scrollY)
}
// Khôi phục state (cách 1 - trong onCreate)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
savedInstanceState?.let { state ->
val query = state.getString("search_query")
searchEditText.setText(query)
}
}
// Khôi phục state (cách 2 - trong onRestoreInstanceState)
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
val position = savedInstanceState.getInt("scroll_position")
recyclerView.scrollTo(0, position)
}Timing:
onSaveInstanceState()→ called afteronStop()(Android 9+) or beforeonStop()(older)onRestoreInstanceState()→ called afteronStart()
💡 Mẹo: Chỉ lưu lightweight data (strings, ids). Dùng ViewModel cho complex data.
Q: Khi nào onDestroy() KHÔNG được gọi?
Trả lời:
onDestroy() không được đảm bảo sẽ được gọi khi:
- System kills process do low memory
- User force stops app từ Settings
- App crashes
// ❌ Don't rely on onDestroy for critical cleanup
override fun onDestroy() {
super.onDestroy()
saveImportantData() // May not be called!
}
// ✅ Use onStop() or lifecycle-aware components
override fun onStop() {
super.onStop()
saveImportantData() // More reliable
}
// ✅ Or use ViewModel's onCleared()
class MyViewModel : ViewModel() {
override fun onCleared() {
super.onCleared()
// Guaranteed to be called when ViewModel is destroyed
cleanup()
}
}2. Fragment Lifecycle
Q: Fragment Lifecycle khác gì Activity Lifecycle?
Trả lời:
Fragment có thêm các callbacks liên quan đến View và host Activity:
| Callback | Mô tả |
|---|---|
onAttach() | Fragment attached to Activity |
onCreate() | Fragment created, no View yet |
onCreateView() | Create and return View hierarchy |
onViewCreated() | View created, safe to access views |
onDestroyView() | View destroyed, Fragment still exists |
onDetach() | Fragment detached from Activity |
class HomeFragment : Fragment(R.layout.fragment_home) {
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentHomeBinding.bind(view)
// Safe to access views here
binding.button.setOnClickListener { /* ... */ }
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null // Prevent memory leak
}
}⚠️ Quan trọng: Luôn set binding = null trong
onDestroyView()để tránh memory leak!
📚 Tìm hiểu thêm: Fragments
Q: Fragment có thể tồn tại khi Activity bị destroy không?
Trả lời:
Có, với setRetainInstance(true) (deprecated) hoặc sử dụng ViewModel:
// ❌ Deprecated approach
class RetainedFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retainInstance = true // Deprecated in newer versions
}
}
// ✅ Modern approach - Use ViewModel
class DataFragment : Fragment() {
private val viewModel: DataViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ViewModel survives configuration changes
viewModel.data.observe(viewLifecycleOwner) { data ->
updateUI(data)
}
}
}3. Lifecycle-Aware Components
Q: LifecycleOwner và LifecycleObserver là gì?
Trả lời:
LifecycleOwner là interface cho classes có lifecycle (Activity, Fragment).
LifecycleObserver là interface để observe lifecycle events.
// Custom LifecycleObserver
class LocationObserver(
private val context: Context
) : DefaultLifecycleObserver {
private var locationManager: LocationManager? = null
override fun onStart(owner: LifecycleOwner) {
// Start listening when Activity/Fragment starts
locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
// Start location updates
}
override fun onStop(owner: LifecycleOwner) {
// Stop listening when Activity/Fragment stops
locationManager = null
// Stop location updates
}
}
// Usage in Activity/Fragment
class MapFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Automatically manages lifecycle
lifecycle.addObserver(LocationObserver(requireContext()))
}
}Lợi ích:
- ✅ Automatic cleanup
- ✅ Avoid memory leaks
- ✅ Reusable components
Q: viewLifecycleOwner vs this (Fragment)?
Trả lời:
| Owner | Lifecycle | Use Case |
|---|---|---|
this | Fragment lifecycle | ViewModel observation |
viewLifecycleOwner | View lifecycle | UI updates, LiveData observation |
class HomeFragment : Fragment() {
private val viewModel: HomeViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ✅ Correct - use viewLifecycleOwner for UI observations
viewModel.data.observe(viewLifecycleOwner) { data ->
updateUI(data) // Safe, auto-removed when view destroyed
}
// ❌ Wrong - may cause crashes after view destroyed
viewModel.data.observe(this) { data ->
updateUI(data) // Dangerous!
}
}
}⚠️ Quan trọng: Luôn dùng
viewLifecycleOwnerkhi observe từonViewCreated()hoặc sau đó.
4. Process Lifecycle
Q: Android xử lý process priority như thế nào?
Trả lời:
Android chia processes thành 5 priority levels:
| Priority | Mô tả | Ví dụ |
|---|---|---|
| Foreground | User đang interact | Visible Activity |
| Visible | Visible nhưng không focus | Activity behind dialog |
| Service | Running service | Music playback |
| Cached | Background, no active components | Recently closed app |
| Empty | No active components | Idle process |
// Check process importance
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningAppProcesses = activityManager.runningAppProcesses
runningAppProcesses.forEach { process ->
when (process.importance) {
ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND -> "Foreground"
ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE -> "Visible"
ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE -> "Service"
ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED -> "Cached"
else -> "Other"
}
}Khi memory thấp:
- System kills lowest priority processes first
- Cached → Service → Visible → Foreground
5. Common Scenarios
Q: Lifecycle khi navigate giữa 2 Activities?
Trả lời:
Khi Activity A start Activity B:
A: onPause()
B: onCreate()
B: onStart()
B: onResume()
A: onStop()Khi back từ B về A:
B: onPause()
A: onRestart()
A: onStart()
A: onResume()
B: onStop()
B: onDestroy()💡 Mẹo:
onPause()của Activity cũ chạy trướconCreate()của Activity mới. Vì vậy không làm heavy work trongonPause().
Q: Lifecycle khi nhận phone call?
Trả lời:
Khi có incoming call (partial cover):
onPause()Khi call screen covers entirely:
onPause()
onStop()Khi end call:
onRestart()
onStart()
onResume()Q: Lifecycle khi Home button pressed?
Trả lời:
onPause()
onStop()
onSaveInstanceState()Khi return to app:
onRestart()
onStart()
onResume()💡 Mẹo:
onDestroy()không được gọi khi nhấn Home button - Activity vẫn còn trong memory.
📝 Practical Tips
Best Practices theo Lifecycle:
| Callback | Nên làm | Không nên |
|---|---|---|
onCreate() | Initialize ViewModel, setup UI | Heavy I/O operations |
onStart() | Register listeners | Start long-running tasks |
onResume() | Resume animations, refresh UI | Network calls |
onPause() | Pause animations | Save data to database |
onStop() | Unregister listeners, save data | Heavy cleanup |
onDestroy() | Final cleanup | Critical saving |
class BestPracticeActivity : AppCompatActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// ✅ Good - observe ViewModel
viewModel.data.observe(this) { updateUI(it) }
}
override fun onStart() {
super.onStart()
// ✅ Good - register lifecycle-aware listeners
registerReceiver(networkReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
}
override fun onStop() {
super.onStop()
// ✅ Good - unregister listeners
unregisterReceiver(networkReceiver)
}
}📚 Tìm hiểu thêm: Activity Lifecycle, ViewModel