Navigation Component & deep links
The Navigation Component replaces manual fragment transactions:
- The nav graph — screens (destinations) and transitions (actions) in one XML/Kotlin graph
- NavController —
navigate(action),popBackStack()— it owns the back stack - Safe Args — generated type-safe
Directionsclasses for arguments: string Bundle-key mistakes become compile errors
Deep links — jumping straight to a screen from a URL:
- Explicit deep links — via PendingIntent (from notifications)
- Implicit deep links —
<deepLink app:uri="bank://transfer/{id}"/>in the graph + anav-graphelement in the manifest; the system maps the URI to a destination and builds a synthetic back stack - App Links — verified ownership of https URLs (
assetlinks.json): the link opens in-app with no chooser
In banking, deep links are risky entry points: if the target requires auth, the link must pass through auth, never jump straight to content.
// nav_graph.xml-də:
// <fragment android:id="@+id/transactionDetail" ...>
// <argument android:name="txId" app:argType="string"/>
// <deepLink app:uri="bank://tx/{txId}"/>
// </fragment>
// Göndərən tərəf — string açar yox, generasiya olunmuş Directions:
findNavController().navigate(
FeedFragmentDirections.actionFeedToTransactionDetail(txId = tx.id)
)
// Qəbul edən tərəf:
private val args: TransactionDetailFragmentArgs by navArgs()
// args.txId — tipli, null-safeType-safe navigation with Safe Args
The auth-gated deep link pattern: when a link arrives and the user is not logged in, store the target route → redirect to login → continue to the stored route after successful auth. Same principle in Compose Navigation. One more rule: never trust deep link parameters — if a transaction id arrives, the server must verify it belongs to this user (the mobile face of IDOR).
🛠 Practice task
Build a 3-screen graph with the Navigation Component and pass arguments via Safe Args.
- Add a deep link to one destination (
app://demo/tx/{id}) and open it withadb shell am start -a android.intent.action.VIEW -d "app://demo/tx/42". - Press back — observe how the synthetic back stack behaves.
- Then add a "login required" gate: store the target route and resume after login.
Done when: the deep link cannot bypass auth and the back button behaves sensibly.
📚 Sources and documentation
- Navigation Componentofficialdeveloper.android.com
- Create a deep link for a destinationofficialdeveloper.android.com
- Android App Linksofficialdeveloper.android.com