Upgrade to Pro — share decks privately, control downloads, hide ads and more …

An Alternative to Fragments - Say Hello to Mortar + Flow

An Alternative to Fragments - Say Hello to Mortar + Flow

Talk about Mortar and Flow - Given at droidcon Berlin - June 2015

Thorben Primke

June 12, 2015
Tweet

More Decks by Thorben Primke

Other Decks in Programming

Transcript

  1. Jelly / SUPER • Mobile Q + A app •

    Jelly was re-built using Mortar and Flow • Unique and fluid UI • Plain views > performance
  2. Jelly / SUPER • Share thoughts and opinions in a

    creative way • More traditional UI • Uses standard list/recyclerView • Fragments could be used • Clean architecture (MVP)
  3. Activity / Fragment • Different but similar lifecycle • Fragments

    were introduced in 3.0 / Honeycomb • Easy to build master / detail UIs with fragments as reusable components • FragmentManager - manages the fragments and transactions Source: https://github.com/xxv/android-lifecycle
  4. Activity / Fragment • Single activity with cached fragments to

    avoid activity overhead - faster transitions • But: • Fragment order on onResume / onAttachFragment • Illegal states when attempting transactions • More complicated lifecycle • View and business logic often cluttered Source: https://github.com/xxv/android-lifecycle
  5. Activity / View • Single activity • Simple views •

    Backstack management ! • (A) Solution: Mortar and Flow Source: https://github.com/xxv/android-lifecycle
  6. Flow • Used to describe screens and handle the navigation

    between them • Each screen is described by a state • Handles screen history • Handles persisting “screens” / paths into the Bundle
  7. • Flows can be extended to handle to nested /

    sub flows • Nested flows - Similar to nested Fragments when used to encapsulate a specific flow within an app. • Navigation stack is reset when flow is exited • Example: Compose Flow Flow
  8. Mortar • Overlay on the application life cycle • Integrates

    with the Context’s getSystemService • Dependency injection • Provides global access to the persistence bundle • MortarScope • Scopes are build upon • AuthScope and UnAuthScope
  9. • BundleService - Any class has access to the Activity’s

    persistence bundle • Provides a Presenter / ViewPresenter • Integrates with Bundler • Can easily persist the Presenter data (onSave method) Mortar
  10. Mortar and Flow Together • Mortar • Leaverages getSystemService to

    provide access to persistance bundle or dependency injection • ViewPresenter for logic and testable • Each Screen in turn has its own Module (adds to Object Graph) • Per MVP concept, both Presenter and View have an instance of one another • Flow • Provides the backstack • Provides definition of the screen
  11. MortarScopes • Starts with root scope • MortarScopes contain different

    Services • getSystemService is used to access services from any context • Scopes can be added for a particular part such as a compose flow or wizard flow to DI state into each of the screens Root ActivityScope MainScreenScope ApplicationModule SettingsModule ActivityModule MainScreenModule
  12. Root ActivityScope WizardScope WizardScreen1Scope ApplicationModule SettingsModule ActivityModule WinzardModule Winzard1Module MortarScopes

    • Starts with root scope • MortarScopes contain different Services • getSystemService is used to access services from any context • Scopes can be added for a particular part such as a compose flow or wizard flow to DI state into each of the screens
  13. Root ActivityScope WizardScope WizardScreen2Scope ApplicationModule SettingsModule ActivityModule WinzardModule Winzard2Module MortarScopes

    • Starts with root scope • MortarScopes contain different Services • getSystemService is used to access services from any context • Scopes can be added for a particular part such as a compose flow or wizard flow to DI state into each of the screens
  14. MortarScopes • Starts with root scope • MortarScopes contain different

    Services • getSystemService is used to access services from any context • Scopes can be added for a particular part such as a compose flow or wizard flow to DI state into each of the screens
  15. MortarScopes • Starts with root scope • MortarScopes contain different

    Services • getSystemService is used to access services from any context • Scopes can be added for a particular part such as a compose flow or wizard flow to DI state into each of the screens
  16. MortarScopes • Starts with root scope • MortarScopes contain different

    Services • getSystemService is used to access services from any context • Scopes can be added for a particular part such as a compose flow or wizard flow to DI state into each of the screens
  17. MortarScopes • Starts with root scope • MortarScopes contain different

    Services • getSystemService is used to access services from any context • Scopes can be added for a particular part such as a compose flow or wizard flow to DI state into each of the screens
  18. Screen Rotation • Presenter is Singleton • Survives activity recreation

    • Screen is not recreated - only View • BundlerService • Save into PersistanceBundle
  19. Screen Rotation • Presenter is Singleton • Survives activity recreation

    • Screen is not recreated - only View • BundlerService • Save into PersistanceBundle
  20. • Presenter is Singleton • Survives activity recreation • Screen

    is not recreated - only View • BundlerService • Save into PersistanceBundle Screen Rotation
  21. Screen Rotation • Presenter is Singleton • Survives activity recreation

    • Screen is not recreated - only View • BundlerService • Save into PersistanceBundle
  22. Screen Rotation • Presenter is Singleton • Survives activity recreation

    • Screen is not recreated - only View • BundlerService • Save into PersistanceBundle
  23. Flow Navigation • Provides navigation for setting / adding to

    the history • Provides back navigation in case there is more than one screen on the history stack • Set method’s logic depends on if a Screen is already in the history or not
  24. Flow Navigation • Provides navigation for setting / adding to

    the history • Provides back navigation in case there is more than one screen on the history stack • Set method’s logic depends on if a Screen is already in the history or not
  25. Flow Navigation • Provides navigation for setting / adding to

    the history • Provides back navigation in case there is more than one screen on the history stack • Set method’s logic depends on if a Screen is already in the history or not
  26. Flow Navigation • Provides navigation for setting / adding to

    the history • Provides back navigation in case there is more than one screen on the history stack • Set method’s logic depends on if a Screen is already in the history or not
  27. Screen Transitions • No default screen animations are provided (by

    Flow) • Flow’s PathContainer needs to be extended • Implement PathContainer’s performTraversal method • SimplePathContainer - provided in the example
  28. • Flow provides both the Flow and FlowDelegate classes •

    Flow holds the navigation history • Each Entry contains the Screen/Path object • FlowDelegate propagates a onSaveInstanceState call to the Flow which persists the history • Each Screen/Path is converted into a Parcelable object • Parcelable converter could for example serialize the Path into JSON Flow History / State Persistence
  29. Lifecycle Integration • Sometimes its necessary to have access to

    onPause, onResume, onActivityResult • Examples: Sign on integrations, external resizing activity, custom Camera integration • Easy way - set explicit callbacks on *Your*Activity • Better - Manager that Presenters can register and unregister for lifecycle events Activity
  30. Lifecycle Integration • Sometimes its necessary to have access to

    onPause, onResume, onActivityResult • Examples: Sign on integrations, external resizing activity, custom Camera integration • Easy way - set explicit callbacks on *Your*Activity • Better - Manager that Presenters can register and unregister for lifecycle events Activity LifecycleOwner
  31. Lifecycle Integration • Sometimes its necessary to have access to

    onPause, onResume, onActivityResult • Examples: Sign on integrations, external resizing activity, custom Camera integration • Easy way - set explicit callbacks on *Your*Activity • Better - Manager that Presenters can register and unregister for lifecycle events Activity LifecycleOwner LifecycleViewPresenter
  32. Settings • Leverage dependency injection to provide a setting to

    any class • Unique Annotation for each setting • Separate SettingsModule that is included in the ApplicationModule (Root) • No SettingsManager needed and each settings value can be provided as needed
  33. Takeaways • Mortar + Flow -> clean (M)VP architecture •

    Mortar’s scopes + objectGraphService = WIN • View and business logic are separated • Presenter can easily be unit tested
  34. Resources • Flow - https://github.com/square/flow • Mortar - https://github.com/square/mortar •

    Example - In the Mortar repo • Mortar / Flow Example App - https://github.com/thorbenprimke/ mortar-flow-example-app