1

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:

  • ProductFragment
  • LoginFragment
  • CartFragment
  • ProfileFragment
  • SearchFragment

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.:

  • a user can start the ProductFragment from the CartFragment
  • In order to see certain product data the user has to log in (LoginFragment)
  • the LoginFragment is also used from the ProfileFragment
  • Through "historic orders" in the ProfileFragment you can also display product details via the ProductFragment.

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.

Michael Schmidt
  • 391
  • 2
  • 14
  • One way to do it is to have the base module contain the shared files. You can even have a module that is not the base module, but it shared between two of the features modules as a module dependency. We made a retail app that has the same setup you created. You just need to bring the shared dependencies down to the base module. – dazza5000 Apr 30 '18 at 18:25
  • This is just a very simplified example. Imagine having like 50 fragments that (at least partly) heavily depend upon each other. If we create a module of a central component as the productFragment and use it in every module we need it, we'd end up with a very chaotic dependency tree. And due to the circular dependencies, that wouldn't even work. – Michael Schmidt May 02 '18 at 14:24
  • Your product fragment goes in a product module and you call that product module from the other modules when you need it. If I have some time I will come up with a simplified example. Thank you. – dazza5000 May 02 '18 at 14:31
  • Your heavy use of fragments might make it difficult to convert to an instant app. https://developer.android.com/topic/instant-apps/faqs Take a look at the: "Can I use a routing activity in my main app..." and "Can I have multiple fragments..." Your mainactivity is like a routing activity where it manages which fragment is pushed to the front, but app links works best with modularized activities. – TWL May 02 '18 at 17:50
  • If you're unable to maintain your fragment experience under 4mb, then you might have to replicate an activity based experience just for instant apps, but first, take a look at which of your fragments will be associated with your URL, then try to branch out from there. Also, take a look at https://stackoverflow.com/questions/44361335/why-use-the-new-android-feature-plugin-over-the-library-plugin to understand how a feature module behaves under app vs instant app. – TWL May 02 '18 at 17:54
  • @dazza5000 If I put the ProductFragment in a seperate module and everything else in another module, I won't be able to call the login fragment from the product fragment anymore, because dependencies go in both directions. That's exactly our problem. – Michael Schmidt May 04 '18 at 07:16
  • The answer of @TWL is what we expected and were afraid of. Currently we can't see any way to extract single screens/fragments from our app to get a module/feature out of it. – Michael Schmidt May 04 '18 at 07:16
  • Michael, did you find a solution or it is not possible? – Andrew Jan 08 '19 at 12:51

1 Answers1

0

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 :)

Michael Schmidt
  • 391
  • 2
  • 14