onStart: Essence, Activity Visibility on Android Screen

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

onStart is an Android lifecycle method that is called when an Activity or Fragment becomes visible to the user. At this moment, the screen appears on the device display but cannot yet interact with the user — input focus is absent until onResume is called. The onStart method is ideal for registering system listeners, connecting to geolocation services, and launching animations that should run while the component is visible on screen. Learn more about the full Activity lifecycle in the article Activity Lifecycle.

Key Takeaways

  • onStart — called when Activity or Fragment becomes visible on screen; precedes onResume
  • Registering listeners — BroadcastReceiver, LocationListener, SensorListener register in onStart and unregister in onStop
  • Animations — start animations that should run while the screen is visible; pause in onStop
  • Bound services — connect to client-server services via bindService in onStart, disconnect in onStop
  • onStart vs onResume — onStart = visibility, onResume = focus + interaction; different levels of screen activity
  • Fragment.onStart — called after Activity.onStart, when Fragment becomes visible in the container
  • onStart/onStop pair — resources connected in onStart must be released in onStop to prevent leaks

The Essence of onStart in Android

onStart is the second method of the Activity lifecycle, called by the system after onCreate (or after onRestart when returning from a stopped state). At the moment onStart is called, the Activity or Fragment becomes visible on screen. The user sees the interface, but the screen is not yet ready for interaction — input focus will appear only after onResume.

The onStart method is part of the “visible lifetime” of an Activity — the interval between onStart and onStop. During this period, the Activity may be partially covered by other windows (e.g., a transparent Activity or dialog window), but its UI remains visible. This distinguishes the visible lifetime from the “foreground lifetime” (onResume — onPause), when the Activity has full input focus.

Understanding this three-level hierarchy is critical for properly distributing code. onCreate — one-time initialization, onStart — connecting visible resources, onResume — exclusive access to exclusive resources. A developer who confuses these levels risks creating memory leaks or incorrect application behavior when switching between screens.

onStart in Activity

In Activity, the onStart method is called every time the screen appears on the display — both on first launch (after onCreate) and when returning from background (after onRestart). Unlike onCreate, onStart can be called multiple times during the life of an Activity instance, so code that should execute every time the screen appears is placed here.

kotlin
class DashboardActivity : AppCompatActivity() {
    private val connectivityReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val isConnected = ... // ConnectivityManager check
            binding?.statusIndicator?.setColor(
                if (isConnected) Color.GREEN else Color.RED
            )
        }
    }

    override fun onStart() {
        super.onStart()
        registerReceiver(
            connectivityReceiver,
            IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
        )
        SensorManager.getInstance().registerStepCounter()
    }

    override fun onStop() {
        unregisterReceiver(connectivityReceiver)
        SensorManager.getInstance().unregisterStepCounter()
        super.onStop()
    }
}

Key rule: all resources connected in onStart must be released in onStop. This ensures that when the Activity is hidden from the screen, it does not consume battery, listen to system events, or occupy memory. Android Studio includes lint rules that warn about registering a BroadcastReceiver without corresponding unregistration.

onStart in Fragment

onStart in Fragment is closely tied to the lifecycle of the host Activity. The Fragment receives the onStart call after its containing Activity has received onStart. However, if the Fragment is added in deferred mode (FragmentTransaction.commit() without addToBackStack), onStart may be called with a delay.

kotlin
class MapFragment : Fragment() {
    private var mapView: MapView? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        mapView = MapView(requireContext())
        return mapView!!
    }

    override fun onStart() {
        super.onStart()
        mapView?.onStart()
        LocationService.connect(requireContext())
    }

    override fun onStop() {
        mapView?.onStop()
        LocationService.disconnect()
        super.onStop()
    }
}

Fragment.onStart specifics: if the Fragment is in a ViewPager with offscreenPageLimit = 1, neighboring fragments will also receive onStart before becoming visible. This can lead to premature listener registration. For such cases, use the setUserVisibleHint() method or check isVisible inside onStart to register listeners only for actually visible fragments.

Difference Between onStart and onResume

The main difference between onStart and onResume is the level of screen activity. onStart signals that the Activity is visible on screen but not necessarily in the foreground. onResume signals that the Activity is in the foreground and has input focus. The difference is demonstrated by a dialog window example: when a Dialog appears over an Activity, the Activity loses onResume (onPause is called) but remains visible — onStart/onStop are not called.

The comparison table clearly shows in which scenarios each method is called:

ScenarioonStartonResume
App launchCalledCalled
Dialog opened over ActivityNot calledonPause (loses focus)
Home button pressedonStop (hidden)onPause → onStop
Return from RecentsonStart (visible)onResume (focus)
Screen rotationonCreate → onStart→ onResume
Incoming callonStop (hidden)onPause → onStop

This table helps the developer decide which method to place specific code into. For example, if the app should pause video playback during any screen overlap (even a dialog), the code goes in onPause. If the video should only stop when the screen is completely hidden, the code goes in onStop.

Registering Listeners and Services

onStart is the optimal place to register listeners that should only work while the Activity is visible on screen. This concerns three main types of system components: BroadcastReceiver for system events, LocationListener for geolocation, and SensorListener for device sensors.

BroadcastReceiver in onStart

BroadcastReceiver is dynamically registered via Context.registerReceiver() in onStart and unregistered in onStop via unregisterReceiver(). Dynamic registration is preferable to static registration (in the manifest) because it limits the receiver’s lifetime to the Activity’s visible period — the app does not wake up from system broadcast messages when the Activity is hidden.

kotlin
private val batteryReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent) {
        val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
        binding?.batteryText?.text = "$level%"
    }
}

override fun onStart() {
    super.onStart()
    registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
}

override fun onStop() {
    unregisterReceiver(batteryReceiver)
    super.onStop()
}

LocationListener and SensorListener

Geolocation and sensors are resource-intensive operations. Requesting GPS updates in onStart and canceling in onStop ensures that the app does not drain battery when the screen is hidden. For fine-tuning, use requestLocationUpdates with a minimum interval and distance — for example, 10 seconds and 10 meters, which provides an optimal balance between accuracy and power consumption.

Animations and onStart

Starting animations in onStart, rather than in onCreate, ensures that the animation starts every time the screen appears. If you start an animation in onCreate, it will only work on the first Activity creation, not when returning from background. onStart is called every time the Activity becomes visible, making it the ideal place to start cyclic animations and transitions.

kotlin
private lateinit var pulseAnimator: ValueAnimator

override fun onStart() {
    super.onStart()
    pulseAnimator.start()
    binding?.loadingIndicator?.animate()?.alpha(1f)?.start()
}

override fun onStop() {
    pulseAnimator.cancel()
    binding?.loadingIndicator?.animate()?.cancel()
    super.onStop()
}

For animations using ObjectAnimator or ValueAnimator, it is important to call cancel() in onStop. If the animation continues running after the Activity is hidden, it uselessly consumes GPU and CPU resources, degrading device performance and accelerating battery drain. Android Studio Profiler (GPU graph) allows you to track active animations and detect leaks.

The onStart/onStop pairing rule also applies to working with the camera for preview (CameraX). Opening the camera in onStart and closing it in onStop ensures that the camera is not blocked for other apps when your app is not visible on screen. Violating this rule is a common cause of negative reviews on Google Play.

Frequently Asked Questions

What is the difference between onStart and onResume for registering listeners?

onStart — for listeners that should work while the screen is visible (BroadcastReceiver, LocationListener, SensorListener). onResume — for resources requiring exclusive access (camera, video capture, speech recognition). System event listeners do not require exclusive access and can work with partial overlap — they are registered in onStart. The camera should only be active with full focus — it is opened in onResume.

Why might onStart not be called?

onStart is always called if the Activity transitions to a visible state. The only scenario without onStart — the Activity is created and immediately finishes (e.g., due to an error in onCreate). In this case, onDestroy is called right after onCreate. But this is an emergency scenario that should not occur in properly written code.

Can onStart be called without onResume?

Yes, onStart may not receive onResume if another Activity or a transparent window opens immediately over the Activity. For example, if an authorization screen is launched after onCreate (Activity A → Activity B), in Activity A onStart is called, but onResume is not — it immediately receives onPause → onStop when overlapped by screen B.

How many times can onStart be called?

onStart can be called multiple times during the life of an Activity instance. Every time the Activity transitions from a hidden state (onStop) to a visible state, onStart is called. In practice, with active app usage, onStart can be called dozens or hundreds of times per session.

Should data be loaded in onStart?

Loading data in onStart is justified if the data should be updated every time the screen appears. For example, a news feed or notification list. However, loading should be asynchronous — via coroutines with lifecycleScope, to avoid blocking the UI thread. For data that does not change between screen appearances, loading once in onCreate is sufficient.

Summary

  • onStart — visible lifecycle method; called when Activity or Fragment appears on screen
  • Registering in onStart — BroadcastReceiver, LocationListener, SensorListener register in onStart and unregister in onStop
  • onStart vs onResume — onStart = visibility, onResume = input focus; different levels for different resource types
  • Animations — start cyclic animations in onStart, stop in onStop; prevents GPU resource leaks
  • Fragment.onStart — tied to Activity.onStart; in ViewPager called for neighboring fragments in advance
  • Pairing rule — all onStart resources must be released in onStop, otherwise memory and battery leaks
  • Data loading — in onStart, load data that should be updated every time the screen appears

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