Single-Activity?
This is an article part of a series. For objectives, fundamentals, project structure, and articles summary, see Android::Simplified
Make sure to read the Decoupling Binding article first!
Repository: https://gitlab.com/migueltt/simpleandroid
There’s has been much debate whether to use the Single-Activity architecture. This has multiple benefits but it all depends on how the app is organized:
- It is not about a “single” Activity, but rather how “screens” are organized — that is, a complete workflow
- A “screen” is any component that displays information to the user — for Android, these could be
Fragments
, and, why not,Activities
- It’s not just adding all your
Fragments
(orActivities
) into anavigation-graph
and reference it using aNavHostFragment
. You must have a clear understading of the use-cases and their data requirements
The Jetpack Navigation API makes the whole app organization much simpler, simplifying how you transition over different sections of the app.
First, you must think about “modules”:
- A module encloses one feature or workflow, and could contain several “screens” — in our case,
Fragments
- You should define a
navigation-graph
for each module - Several
navigation-graphs
could be then referenced from a main one (usingnested-graphs
), or, it could be directly attached to aNavHostFragment
In our Simple::Android
app, module testui
(variant debug
) encloses 10 different Fragments
that implement almost every UI-widget — this has been done just to verify that all our future modules will not be impacted by updates on UI libraries (e.g. Material Design Components.)
Two different approaches have been implemented, providing the same functionality:
ActivityTestMain
contains its ownNavHostFragment
— this effectively makes moduletestui
self-contained and within its own “window”FragmentTestMain
contains its ownNavHostFragment
— this effectively makes moduletestui
self-contained but within theActivityMain
“window”
The implementation differs on how the back-pressed events are handled.
Depending on how you want to manage each module it is quite simple to decouple and manage the flow within your module, plus having the benefit of managing ViewModels at different levels:
- If the whole app requires some shared data (e.g. Login Status), just define a ViewModel at the
Activity
level — useactivityViewModels(..)
- If all screens within a module should use the same data, just define a ViewModel at the
navigation-graph
level — usenavGraphViewModels(..)
- If a screen requires just data for itself, just define a ViewModel at the
Fragment
level — useviewModels(..)
Remember, the objective is to have an architecture like this: