androidandroid-fragmentsmodularityandroid-instant-appsmodularization

Modularize Single Activity Android Application with circular fragment dependencies


We have an app with bottom bar navigation. The navigation is in our MainActivity. We manage navigation between the different screens of the app with fragments. E.g. there are:

In our MainActivity we have a method pushFragment(Fragment fragment) which is responsible for replacing the current fragment with a new fragment. Between our different fragments there are a lot of dependencies. E.g.:

Fragment Dependencies

We now want to modularize our Android app to make use of Instant Apps, faster build times, and all the other advantages. Ideally we'd like to have a module for each fragment. However due to dependencies like the ones I just described we are not able to create a linear dependency hierachy and have no idea how to build our modules.

Every time we try to pick our first module to extract from the app module, we end up with a lot of dependencies we also have to move to the new module.

The only solution we currently see is to change the way we navigate between the fragments, but we can't think of a way on how to do that.


Solution

  • We sort of found a start of a solution:

    We hava an interface NavigationHelper that declares methods to navigate to other fragments (startProfileFragment, startLoginFragment, startProductFragment, ...). This interface is in our libBase. It is implemented in the Activity, which is in the app module.

    In the Fragment we cast the context in onAttach to NavigationHelper (also check, that the context is a NavigationHelper and throw an exception otherwise):

    private NavigationHelper mNavigationHelper;
    
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof NavigationHelper){
            mNavigationHelper = (NavigationHelper) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement NavigationHelper");
        }
    } 
    

    Then you can just call mNavigationHelper.startProfileFragment() to switch Fragments.

    Thanks to @Andrey to remind me to publish that :)