Context, Application & Manifest Interview Questions

ANDROID › System

Walk me through, concretely, what actually leaks when you hold an Activity Context past its lifecycle. What's really being kept alive in memory, step by step?

What a strong answer covers: Holding an Activity Context, directly or indirectly through a View, Drawable, Adapter, or listener that references it, keeps that Activity object reachable from a GC root; because the Activity holds its entire View hierarchy, and each View can hold Bitmaps, listeners, and child views, the whole tree stays resident even after the Activity is destroyed and a new instance is created on rotation. The old Activity plus its full View tree stays pinned in memory for the lifetime of whatever long-lived object, a singleton, a static field, an event bus subscription, is holding the reference; a strong answer traces this chain rather than just saying it leaks memory.

You're designing a DI setup for a new app. Walk me through your rule for which Context each provided dependency should receive, and where in the graph you'd catch it if someone accidentally injected an Activity context into a singleton-scoped class.

What a strong answer covers: The rule is to scope the Context to the scope of the consumer: anything with application or singleton scope, a Retrofit client, a repository, an analytics wrapper, should only ever receive the application context since it must outlive any single screen; anything that genuinely needs an Activity context, like inflating a themed layout or showing a Dialog, should be scoped to that Activity or Fragment and never escape into a broader-scoped class. In a framework like Hilt, application context and activity context are distinct qualifiers, so injecting an activity-scoped context into a class installed in the singleton component is a compile-time graph error rather than a runtime leak, which is a concrete advantage of DI over passing Context around manually.

Application.onCreate() is often treated as 'the place to init everything.' What's actually wrong with that instinct at scale, and how does the App Startup library's design address it without you manually ordering things by hand?

What a strong answer covers: Application.onCreate() runs synchronously on the main thread before the first Activity is even created, so cramming every SDK init in there directly delays time to first frame, and doing it manually requires hand-ordering everything, since SDK B might need SDK A initialized first, which becomes unmaintainable as the number of libraries grows. App Startup addresses this by having each Initializer explicitly declare its own dependencies(), so the library builds a dependency graph and topologically sorts initialization inside a single ContentProvider, which itself runs before Application.onCreate and piggybacks on an otherwise-wasted phase, and it lets you disable auto-run initializers to trigger them lazily instead without losing the dependency guarantees when you do.

Back to Context, Application & Manifest