Android App Architecture & Navigation

108056ccba92f98fdbbabad534537573?s=47 Bryan Herbst
September 04, 2018

Android App Architecture & Navigation

A look into the new navigation architecture component and how it fits with Fragments and Activites

108056ccba92f98fdbbabad534537573?s=128

Bryan Herbst

September 04, 2018
Tweet

Transcript

  1. Android App Architecture & Navigation Bryan Herbst (@bryancherbst)

  2. Activities & Fragments

  3. STOP

  4. STOP If you like what you have, keep it

  5. When to use what?

  6. Where we’ve been

  7. In the beginning there was Activity

  8. Activity Entry point to your application

  9. Activity Entry point to your application Has a Window

  10. Activity Entry point to your application Has a Window Has

    a lifecycle
  11. Activity Entry point to your application Has a Window Has

    a lifecycle Responds to configuration changes
  12. Activity Entry point to your application Has a Window Has

    a lifecycle Responds to configuration changes ActivityManager handles back stack
  13. Activity Layout inflation View manipulation Click handlers Animations Navigation Menu

    creation Menu item callbacks Database calls Networking calls Disk I/O Sensor input Geolocation
  14. Activity Window transitions can be difficult !

  15. Activity Window transitions can be difficult A lot of plumbing

    !
  16. Activity Window transitions can be difficult A lot of plumbing

    Nuanced (and limited) backstack !
  17. Enter Honeycomb (3.0)

  18. None
  19. Fragments!

  20. Fragment Has lifecycle (less than Activity)

  21. Fragment Has lifecycle (less than Activity) Backstack via FragmentManager

  22. Fragment Has lifecycle (less than Activity) Backstack via FragmentManager Composable

  23. Fragment Has lifecycle (less than Activity) Backstack via FragmentManager Composable

    Belong to an Activity
  24. Fragments Transactions are annoying !

  25. Fragments Transactions are annoying Lifecycles are annoying !

  26. Fragments Transactions are annoying Lifecycles are annoying Can still be

    too big !
  27. Fragments Transactions are annoying Lifecycles are annoying Can still be

    too big Bugs !
  28. Fragments Transactions are annoying Lifecycles are annoying Can still be

    too big Bugs Differences from Activity !
  29. Meanwhile

  30. View-based architecture

  31. View Draws things Reacts to user interaction

  32. View Almost no lifecycle No backstack !

  33. Where are we now?

  34. Single activity app Easier to manage transitions

  35. Single activity app Easier to manage transitions Composable UI elements

  36. Single activity app Easier to manage transitions Composable UI elements

    Google can be opinionated
  37. Don’t like lifecyles? Use Lifecycle

  38. class MainActivity : Activity { override fun onStart() { super.onStart()

    analytics.reportStart() } }
  39. activity.lifecycle .addObserver(AnalyticsObserver()) class AnalyticsObserver : LifecycleObserver { @OnLifecycleEvent(ON_START) fun trackPageLoad()

    { analytics.reportStart() } }
  40. activity.lifecycle .addObserver(AnalyticsObserver()) class AnalyticsObserver : LifecycleObserver { @OnLifecycleEvent(ON_START) fun trackPageLoad()

    { analytics.reportStart() } }
  41. Fragment refresher

  42. Which Fragments? Framework fragments Support fragments

  43. Which Fragments? Framework fragments Support fragments ! "

  44. Fragment transactions

  45. Fragment transactions fragmentManager.beginTransaction()

  46. Fragment transactions fragmentManager.beginTransaction() .add()

  47. Fragment transactions fragmentManager.beginTransaction() .remove()

  48. Fragment transactions fragmentManager.beginTransaction() .replace()

  49. Fragment transactions fragmentManager.beginTransaction() .show()

  50. Fragment transactions fragmentManager.beginTransaction() .hide()

  51. Fragment transactions fragmentManager.beginTransaction() .addToBackstack()

  52. Fragment transactions fragmentManager.beginTransaction() .commit()

  53. Fragment transactions fragmentManager.beginTransaction() .add() .replace() .hide() .addToBackstack() .commit()

  54. Transactions are asynchronous

  55. The IllegalStateException com.awesomeapp E/MainActivity: java.lang.IllegalStateException: Cannot perform this action after

    onSaveInstanceState
  56. The IllegalStateException FM State

  57. The IllegalStateException FM State add()

  58. The IllegalStateException FM State add()

  59. The IllegalStateException FM State add() hide()

  60. The IllegalStateException FM State add() hide() onStop()!!

  61. The IllegalStateException FM State add() hide() onStop()!! Persisted add() hide()

  62. The IllegalStateException FM State onStart() Persisted add() hide()

  63. The IllegalStateException FM State add() hide() Persisted add() hide() replace()

  64. The IllegalStateException After onSaveInstanceState any future changes may be lost

  65. Okay, but async transactions suck

  66. Commit() commit() executePendingTransactions() commitAllowingStateLoss() commitNow() commitNowAllowingStateLoss()

  67. Commit() commit() executePendingTransactions() commitAllowingStateLoss() commitNow() commitNowAllowingStateLoss()

  68. Commit() commit() executePendingTransactions() commitAllowingStateLoss() commitNow() commitNowAllowingStateLoss()

  69. Commit() commit() executePendingTransactions() commitAllowingStateLoss() commitNow() commitNowAllowingStateLoss()

  70. Back stack addToBackStack(null)

  71. Back stack popBackStack()

  72. Back stack addToBackStack("screenA")

  73. Back stack addToBackStack("screenA")

  74. Back stack addToBackStack("screenB")

  75. Back stack addToBackStack("screenC")

  76. Back stack popBackStack("screenA", 0)

  77. But that’s a lot of work

  78. Navigation

  79. Navigation Challenges Transitions

  80. Navigation Challenges Transitions Back stack management

  81. Navigation Challenges Transitions Back stack management Up vs. back

  82. Navigation Challenges Transitions Back stack management Up vs. back Passing

    data
  83. Navigation Challenges Transitions Back stack management Up vs. back Passing

    data Deep linking
  84. Android Jetpack: Navigation

  85. Principles Navigation is a stack

  86. Principles Navigation is a stack Up never exits the app

  87. Principles Navigation is a stack Up never exits the app

    Up = Back within your app
  88. Principles Navigation is a stack Up never exits the app

    Up = Back within your app Deep linking should yield the same stack
  89. Navigation (the library)

  90. Navigation library No more Fragment transactions!

  91. Navigation library No more Fragment transactions! No more startActivity()!

  92. Navigation library No more Fragment transactions! No more startActivity()! Just

    call navigate()
  93. Navigation Graph All the destinations in your app, plus the

    action that connect them.
  94. Navigation Graph New XML resource type!

  95. Navigation tooling

  96. Navigator What destination types are available?

  97. NavHost Where do those destinations reside?

  98. NavController How do I get there?

  99. Current Navigators ActivityNavigator

  100. Current Navigators ActivityNavigator FragmentNavigator

  101. <fragment android:id="@+id/navHost" android:name= "androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" />

  102. <fragment android:id="@+id/navHost" android:name= "androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph" />

  103. Do the navigation Navigation .findNavController(view) .navigate(R.id.action_id)

  104. Destinations: Deep link Destinations can have deep links <fragment android:id="@+id/home”

    android:name="com.example.HomeFragment" android:label="fragment_home"> <deepLink app:uri="http://example.com/detail"/> </fragment>
  105. Actions: Animations Actions can have transition animations <action android:id="@+id/action_home_to_detail" app:destination="@id/detail"

    app:popEnterAnim="@anim/slide_in_left" app:popExitAnim="@anim/slide_out_right" app:enterAnim="@anim/slide_in_right" app:exitAnim="@anim/slide_out_left"/>
  106. Actions: back stack Each action can define its own behavior

    <action android:id="@+id/home_to_details" app:destination="@id/details” app:popUpTo="@id/splash” app:popUpToInclusive="false" />
  107. Arguments Actions can all have arguments <fragment> <argument android:name="name" android:defaultValue="Joe"

    /> </fragment>
  108. Arguments Works with deep links! <fragment> <argument android:name="name" android:defaultValue="Joe" />

    <deepLink app:uri="example.com/{name}" /> </fragment>
  109. Safeargs androidx.navigation.safeargs

  110. Safeargs androidx.navigation.safeargs Generates argument wrapper classes

  111. Safeargs Demo time!

  112. Demo time!

  113. Custom destination You can make your own Navigator!

  114. What’s missing Some integration with common elements like bottom navigation

  115. What’s missing Some integration with common elements like bottom navigation

    Shared element transitions
  116. What’s missing Some integration with common elements like bottom navigation

    Shared element transitions Nested navigation graphs
  117. What’s missing Some integration with common elements like bottom navigation

    Shared element transitions Nested navigation graphs Result data (e.g. startActivityForResult())
  118. What if I want to migrate to Navigation?

  119. I currently have…

  120. Single Activity

  121. Single Activity Set up navigation graph

  122. Single Activity Set up navigation graph Each Fragment is a

    destination
  123. Single Activity Set up navigation graph Each Fragment is a

    destination Every transaction is an action
  124. Single Activity Set up navigation graph Each Fragment is a

    destination Every transaction is an action Define arguments
  125. Single Activity Set up navigation graph Each Fragment is a

    destination Every transaction is an action Define arguments Replace transactions with NavController.navigate()
  126. Multiple activities Start by making a graph for each Activity

  127. Multiple activities Start by making a graph for each Activity

    If you want a single Activity, combine Activities one screen at a time
  128. Activity Chrome

  129. Activity Chrome CoordinatorLayout .setStatusBarBackgroundColor()

  130. Activity Features <activity android:name=".MainActivity" android:windowSoftInputMode="adjustPan" />

  131. Activity Features <activity android:name=".MainActivity" android:windowSoftInputMode="adjustPan" /> activity.window .setSoftInputMode(SOFT_INPUT_ADJUST_PAN)

  132. More complex Watch for updates! Provide feedback!

  133. Resources https://developer.android.com /topic /libraries /architecture /navigation