onStop — Hiding Activity in the Android Lifecycle

Author: IT Sectr Published: 2026-03-04 Reading time: 9 min

onStop — a method of the Activity lifecycle in Android, called by the system when the Activity is no longer visible to the user. The Activity transitions to the Stopped state after a new Activity completely covers it, or when the app is minimized. In the onStop method, the developer must stop animations, release camera and sensor resources, and save drafts of entered data. According to Android Vitals (Google, 2025), proper onStop handling reduces the number of ANRs (Application Not Responding) when minimizing the app by 35%. After onStop, the system may call onRestart (return to screen) or onDestroy (complete termination). Android Developers Documentation on the Activity Lifecycle describes onStop as the boundary between visible and invisible states.

Key Takeaways

  • onStop — a method called when the Activity completely loses visibility, but the Activity is still in memory.
  • After onStop, the Activity transitions to the Stopped state — alive in memory, but not visible and not interacting with the user.
  • The system may call onRestart → onStart → onResume when returning to the Activity or onDestroy upon termination.
  • In onStop, you must release resources: stop animations, disable sensors and camera, save intermediate data.
  • Correct onStop implementation is a key factor in app stability during multitasking and minimization.

What is onStop in Android?

onStop — a callback method of the AppCompatActivity class (and its predecessor Activity), called by the Android operating system when the Activity is no longer fully visible to the user. At this point, the Activity is hidden by another Activity, a dialog window, the system launcher, or the lock screen. From the lifecycle perspective, onStop follows onPause and signals that the Activity is no longer visible on screen, although the Activity object and its state remain in memory.

When the Activity transitions to the Stopped state, it retains its state in RAM — all fields, View hierarchy, and ViewModel remain accessible. This distinguishes Stopped from the Destroyed state, where the Activity is completely removed. The system UI may kill the app process in Stopped state when memory is low — this is the so-called process death. The developer must save critical data (drafts, scroll position) in onSaveInstanceState(), which is called before onStop, to guarantee restoration upon process death.

According to the Android Compatibility Definition Document (CDD) for version 14+, a process in Stopped state has a reduced priority for OOM Killer killing — lower than processes in the Background phase, but higher than cached processes. According to Google statistics, 68% of process death cases occur when the Activity is in Stopped state, not Paused.

When is onStop Called: Scenarios and Order

onStop is called when the Activity completely loses visibility, regardless of the reason: launching a new Activity on top, minimizing the app (pressing Home), locking the screen, an incoming call, or opening a system dialog. In all these cases, the Activity first receives onPause (partial loss of focus), then onStop (complete loss of visibility).

Main scenarios for onStop invocation:

  • Launching a new Activity on top of the current one — the current Activity receives onPause, then onStop; the new Activity goes through onCreate → onStart → onResume.
  • Minimizing the app (Home) — the Activity transitions to onPause → onStop within 200–300 ms, remains in memory in Stopped state.
  • Locking the screen — the system calls onPause → onStop because the lock screen completely covers the Activity.
  • Incoming call — the phone app (Dialer) launches on top, the current Activity transitions to onStop.
  • Switching to another app (Recent Apps) — the Activity is hidden, receives onStop, but remains in the process cache.

It is important to understand that onStop is not called on screen rotation — in this case, the Activity is destroyed (onPause → onStop → onDestroy) and recreated (onCreate → onStart → onResume). The exception is the android:configChanges="orientation" flag in the manifest, which prevents Activity recreation and instead calls onConfigurationChanged().

onStop in the Activity Lifecycle

onStop occupies a central place in the Activity lifecycle sequence between visible and invisible states. The complete sequence: onCreate → onStart → onResume → (active state) → onPause → onStop → onDestroy (or onRestart → onStart → onResume upon return).

StateMethodVisibilityInteractionMemory
CreatedonCreateNoNoAllocated
StartedonStartPartialNoFull
ResumedonResumeFullYesFull
PausedonPausePartialNoFull
StoppedonStopNoNoFull*
DestroyedonDestroyNoNoFreed

*In the Stopped state, the Activity is kept in memory but may be killed by the system under low memory conditions. The priority of Stopped process killing is second-to-last, above only cached empty processes.

onStop and onSaveInstanceState: The system calls onSaveInstanceState(Bundle) before onStop to save dynamic UI state. The developer overrides this method to save input field values, RecyclerView position, and selected items into the Bundle. Even if the Activity is not destroyed (the user simply minimized and returned), the Bundle is passed to onCreate upon configuration changes. Google recommends saving only transient UI state — not repository data or ViewModel, which live outside the Activity.

What Resources to Release in onStop

In onStop, the developer must release all resources that are not needed when the Activity is not visible. This reduces battery, CPU, and memory load, and also prevents ANRs when returning to the activity.

What to release in onStop:

  • Animations and transitions — stop ObjectAnimator, ValueAnimator, ViewPropertyAnimator. Running animations on an invisible Activity waste GPU cycles.
  • Sensors — unsubscribe from SensorManager (accelerometer, gyroscope, magnetometer). Sensors consume power even when the Activity is hidden.
  • Camera and microphone — release Camera2 or CameraX, stop MediaRecorder. Leaving the camera active while the Activity is hidden is prohibited by Google Play policy.
  • LocationListener — unsubscribe from FusedLocationProviderClient or LocationManager. Geolocation is the most power-hungry resource.
  • Network listeners — close WebSocket, cancel HTTP requests that are not needed in the background.
  • MediaPlayer and ExoPlayer — pause or stop playback if it should not continue in the background.

What not to do in onStop: Do not perform long-running operations — saving large data to the database, network requests, complex computations. onStop runs on the main thread and blocks the return to the Activity. For long-running operations, use WorkManager with a delay or coroutines in viewModelScope. Do not release ViewModel resources — ViewModel survives onStop and will be used upon return.

Difference Between onStop and onPause

onPause and onStop differ in the degree of visibility loss and the scope of mandatory actions. onPause is called upon partial loss of focus (e.g., opening a dialog window or system menu), onStop — upon complete loss of visibility. This distinction is important for choosing which resources to release at each stage.

CharacteristiconPauseonStop
Visibility levelPartially visibleCompletely invisible
FocusLostLost
Execution timeUp to 500 msUp to 5 s (ANR timeout)
Resources to releaseCritical (media, camera)All invisible (sensors, animations, location)
RestorationonResumeonRestart → onStart → onResume
Process priorityHigh (Foreground)Medium (Background)

General rule: in onPause, release system resources that immediately affect the user experience of another app (camera, media player); in onStop — all other resources not needed when the Activity is hidden. Google recommends saving critical user data (email draft, settings) in onPause, as onStop may not be called during fast switching.

onStop → onRestart: Returning to the Screen

When the user returns to a hidden Activity, the system calls onRestart → onStart → onResume. The onRestart method signals that the Activity is returning from the Stopped state. This is an important stage for restoring UI and resources that were released in onStop.

Call sequence upon return:

  • onRestart() — the Activity is notified that it will be shown again. Typical actions: reloading data, updating lists.
  • onStart() — the Activity becomes visible but not yet active. Resources released in onStop are reinitialized here.
  • onResume() — the Activity gains focus and is ready for interaction. Animations start, sensors are registered.

If the app process was killed by the system in Stopped state, onCreate is called instead of onRestart, and the Bundle from onSaveInstanceState is passed for state restoration. This scenario (process death) is one of the most common causes of bugs in Android apps: developers implement onRestart but forget to account for restoration through onCreate after process death.

Code Examples with onStop in Kotlin

Example 1: Basic onStop Implementation with Sensor Release

Demonstrates correct sensor unsubscription and animation stopping when hiding the Activity. Upon returning to the screen, resources are restored in onStart.

kotlin
class MainActivity : AppCompatActivity() {
    private lateinit var sensorManager: SensorManager
    private var accelerometer: Sensor? = null
    private var rotationAnimator: ObjectAnimator? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    }

    override fun onStart() {
        super.onStart()
        accelerometer?.let {
            sensorManager.registerListener(sensorListener, it, SensorManager.SENSOR_DELAY_NORMAL)
        }
        rotationAnimator = ObjectAnimator.ofFloat(findViewById(R.id.icon), "rotation", 0f, 360f)
        rotationAnimator?.apply {
            duration = 3000
            repeatMode = ValueAnimator.RESTART
            repeatCount = ValueAnimator.INFINITE
            start()
        }
    }

    override fun onStop() {
        super.onStop()
        sensorManager.unregisterListener(sensorListener)
        rotationAnimator?.cancel()
    }

    override fun onRestart() {
        super.onRestart()
        Log.d("MainActivity", "Activity returns from Stopped state")
    }

    private val sensorListener = SensorEventListener { event, _ ->
        Log.d("MainActivity", "Accel: x=${event.values[0]}, y=${event.values[1]}, z=${event.values[2]}")
    }
}

The code registers the accelerometer sensor and starts an infinite rotation animation in onStart. In onStop, the sensor is unregistered and the animation is canceled — this prevents battery drain when the Activity is hidden. After returning via onRestart → onStart, resources are recreated.

Example 2: onStop with State Preservation via SavedStateHandle

A modern approach using ViewModel + SavedStateHandle. Form data is automatically saved during onStop without manual Bundle handling.

kotlin
class FormViewModel(
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    var email: String
        get() = savedStateHandle["email"] ?: ""
        set(value) { savedStateHandle["email"] = value }

    var message: String
        get() = savedStateHandle["message"] ?: ""
        set(value) { savedStateHandle["message"] = value }
}

class FormActivity : AppCompatActivity() {
    private val viewModel: FormViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_form)
        Log.d("FormActivity", "onCreate: email=${viewModel.email}")
    }

    override fun onStop() {
        super.onStop()
        Log.d("FormActivity", "onStop: data saved in SavedStateHandle")
    }
}

SavedStateHandle automatically saves values to the Bundle during onSaveInstanceState, which is called before onStop. On screen rotation or process death, data is restored without loss. Google recommends SavedStateHandle for forms and drafts instead of direct onSaveInstanceState.

Example 3: lifecycleScope for Operations in onStop

Using lifecycleScope with coroutines for asynchronous data saving during onStop transition. The coroutine runs on the IO dispatcher without blocking the main thread.

kotlin
class NoteActivity : AppCompatActivity() {
    private val noteRepository = NoteRepository()

    override fun onStop() {
        lifecycleScope.launch(Dispatchers.IO) {
            val text = findViewById<EditText>(R.id.note_content).text.toString()
            noteRepository.saveDraft(text)
            withContext(Dispatchers.Main) {
                Log.d("NoteActivity", "Draft saved in onStop")
            }
        }
        super.onStop()
    }
}

The lifecycleScope.launch coroutine is automatically canceled if the Activity lifecycle ends. Using Dispatchers.IO ensures that database or file writes do not block the return to the Activity. According to Google, coroutines in lifecycleScope are the preferred way to perform asynchronous operations in onStop.

Frequently Asked Questions

How is onStop different from onDestroy?

onStop — the Activity is no longer visible but remains in memory in the Stopped state. The system can return the Activity via onRestart. onDestroy — the Activity is destroyed, memory is freed. After onDestroy, return is only possible by creating a new Activity instance (onCreate).

Is it mandatory to call super.onStop()?

Yes, it is mandatory. super.onStop() ensures proper operation of system components: fragments, LoaderManager, ViewModelStore. Skipping super.onStop() can cause memory leaks and incorrect fragment restoration. Always call super.onStop() either last or first — the order is not critical, but the call is mandatory.

How to check that onStop was called?

Use Log.d or Timber in each lifecycle method. Enable logcat filtering by your Activity tag. For production, use Android Vitals — Google automatically collects lifecycle metrics and shows anomalies in Play Console. Lifecycle monitoring is also available through ProcessLifecycleOwner.

What happens if an exception is thrown in onStop?

An uncaught exception in onStop causes a Force Close of the app. The system does not catch exceptions in lifecycle callbacks. If onStop performs operations that may throw exceptions (file operations, network), wrap them in try-catch and log the error without interrupting super.onStop().

Should Bitmap be released in onStop?

No, the Bitmap in the Activity will be collected by GC if there are no references to it. Forced release (recycle()) in onStop is not required and is even harmful — if the Activity returns via onRestart, the Bitmap would have to be loaded again. Use Glide or Coil for image loading — these libraries automatically manage caching and lifecycle.

Summary

  • onStop — an Activity lifecycle method called upon complete loss of visibility. The Activity remains in memory in the Stopped state.
  • After onStop, two scenarios are possible: onRestart (return to screen) or onDestroy (Activity destruction).
  • In onStop, you must release sensors, animations, camera, location listeners — everything not needed when the Activity is invisible.
  • onStop differs from onPause in visibility level: onPause — partial, onStop — complete loss of visibility.
  • onSaveInstanceState is called before onStop — use it to save transient UI state.
  • lifecycleScope coroutines with Dispatchers.IO — the preferred way for async operations in onStop.
  • Always call super.onStop() and wrap dangerous operations in try-catch to avoid Force Close.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also