Bỏ qua để đến nội dung

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.


Trả lời:

Activity Lifecycle gồm 7 callback methods chính:

flowchart TD
A["onCreate()"] --> B["onStart()"]
B --> C["onResume()"]
C --> D["RUNNING"]
D --> E["onPause()"]
E --> F["onStop()"]
F --> G["onDestroy()"]
E -.-> C
F -.-> B
G -.-> A
style D fill:#c8e6c9
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()?

Phần tiêu đề “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 after onStop() (Android 9+) or before onStop() (older)
  • onRestoreInstanceState() → called after onStart()

💡 Mẹo: Chỉ lưu lightweight data (strings, ids). Dùng ViewModel cho complex data.


Trả lời:

onDestroy() không được đảm bảo sẽ được gọi khi:

  1. System kills process do low memory
  2. User force stops app từ Settings
  3. 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()
}
}

Q: Fragment Lifecycle khác gì Activity Lifecycle?

Phần tiêu đề “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:

flowchart TD
A["onAttach()"] --> B["onCreate()"]
B --> C["onCreateView()"]
C --> D["onViewCreated()"]
D --> E["onStart()"]
E --> F["onResume()"]
F --> G["RUNNING"]
G --> H["onPause()"]
H --> I["onStop()"]
I --> J["onDestroyView()"]
J --> K["onDestroy()"]
K --> L["onDetach()"]
style G fill:#c8e6c9
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?

Phần tiêu đề “Q: Fragment có thể tồn tại khi Activity bị destroy không?”

Trả lời:

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

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

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 viewLifecycleOwner khi observe từ onViewCreated() hoặc sau đó.


Q: Android xử lý process priority như thế nào?

Phần tiêu đề “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

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ước onCreate() của Activity mới. Vì vậy không làm heavy work trong onPause().


Trả lời:

Khi có incoming call (partial cover):

onPause()

Khi call screen covers entirely:

onPause()
onStop()

Khi end call:

onRestart()
onStart()
onResume()

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.


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