tezvyn:

How do you navigate between feature modules without direct dependencies?

Curated by the Tezvyn teamSource: developer.android.comadvanced
How do you navigate between feature modules without direct dependencies?

This tests architectural decoupling in multi-module Android apps. A great answer describes a shared navigation contract or deep-link router that lets features stay independent. Recommending direct Gradle dependencies between features is a major red flag.

WHAT THIS TESTS: The interviewer wants to see if you understand how to enforce strict module boundaries in a large Android codebase. They care about inversion of control, build-time independence, and whether you know how to route screens without leaking implementation details across Gradle modules. This is fundamentally about the dependency rule: feature modules should never know about each other.

A GOOD ANSWER COVERS: First, introduce a contract or api module such as :navigation_contract or :core_navigation that holds route constants, sealed classes, or navigator interfaces. Second, explain that the app module or a dedicated router module wires concrete destinations to these abstractions at runtime or compile time. Third, mention dynamic registration where each feature contributes its navigation graph or route handler to a central registry, often via dependency injection. Fourth, note practical Android patterns like the Navigation Component with dynamic feature modules, deep link URIs resolved by an intermediary, or compile-safe routers built with Kotlin Symbol Processing. Emphasize that the feature module only exposes its entry points, never its internals.

COMMON WRONG ANSWERS: Saying you would let :feature_profile directly depend on :feature_settings is an immediate red flag because it creates a hard dependency graph and kills parallel build benefits. Proposing a single :common module that every feature imports is almost as bad; it becomes a dumping ground and still couples features implicitly. Another trap is suggesting reflection-based navigation without explaining how you maintain type safety or handle ProGuard and R8 obfuscation in production.

LIKELY FOLLOW-UPS: The interviewer may ask how you handle arguments safely across module boundaries, how you would deep link into a dynamic feature module that is not yet installed, or how you test navigation logic in isolation. They might also probe whether your router should live in the app module or its own library, and how you prevent circular dependencies if multiple features need bidirectional routing.

ONE CONCRETE EXAMPLE: Imagine :feature_profile needs to open :feature_settings. You define a SettingsRoute data class in :navigation_contract. The :feature_settings module provides a SettingsRouteHandler implementation registered in a Dagger or Hilt multibinding map keyed by the route class. The :app module holds a NavigationDispatcher that looks up the handler and delegates to the Android Navigation Component. :feature_profile only knows the SettingsRoute type from the contract module; it has no Gradle dependency on :feature_settings and cannot access its fragments or view models directly.

Source: developer.android.com

Read the original → developer.android.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.

How do you navigate between feature modules without direct dependencies? · Tezvyn