Android Fragments: FragmentFactory

Husayn Hakeem
ProAndroidDev
Published in
4 min readFeb 12, 2020

Fragment constructor injection is now -and has been for a while- supported in Android thanks to FragmentFactory. While it isn’t an API developers have to use, it can be regarded as a better design approach in certain situations and can help when testing Fragments with external dependencies.

This article explains what a FragmentFactory is, how and when to use it, and how it behaves with nested Fragments.

What is a FragmentFactory?

TL;DR A class used to control the instantiation of Fragment instances.

Traditionally, a Fragment instance could only be instantiated using its default empty constructor. This is because the system would need to reinitialize it under certain circumstances like configuration changes and the app’s process recreation. If it weren’t for the default constructor restriction, the system wouldn’t know how to reinitialize the Fragment instance.

FragmentFactory was created to work around this limitation. It helps the system create a Fragment instance by providing it with the necessary arguments/dependencies needed to instantiate the Fragment.

How to use a FragmentFactory?

TL;DR By extending FragmentFactory and overriding FragmentFactory#instantiate(), then assigning it to a FragmentManager.

If your Fragment has a non-empty constructor, you will need to create a FragmentFactory that will handle initializing it. This is done by extending FragmentFactory, and overriding its method FragmentFactory#instantiate().

FragmentFactory usage example

Fragments are managed by FragmentManagers, so it’s only natural that the FragmentFactory needs to be attached to a FragmentManager in order to be used. More specifically, it must be assigned to the FragmentManager of the component that will contain the Fragment, this can be an Activity or another Fragment. More on this below.

When should a FragmentFactory be assigned to a FragmentManager?

TL;DR Before the parent Activity#onCreate() and Fragment#onCreate() are called.

The FragmentFactory responsible for initializing a Fragment inside a component -Activity or parent Fragment- should be set before the Fragment is ever created. This means:

  • Before the component’s View is created, if the Fragment is defined in an XML layout using the fragment tag <fragment> or a FragmentContainerView.
  • Before the component creates the Fragment, if the Fragment is dynamically added using a FragmentTransaction.
  • Before the system restores the Fragment, if the Fragment is being recreated after a configuration change or the app’s process restart.

Given these restrictions, it’s safe to assign the FragmentFactory to the component’s FragmentManager before Activity#onCreate() and Fragment#onCreate() -which are the base classes of your Activity and Fragment- are called, as both these calls handle reinitializing previous Fragments, and run before creating the view.

In practice, this means that the FragmentFactory should be assigned before calling super#onCreate().

When to set a FragmentFactory in an Activity
When to set a FragmentFactory in a Fragment

Do you need to use a FragmentFactory?

TL;DR No, but in certain situations a FragmentFactory might be the better design option.

So far, you’ve probably been creating your Fragments using their default constructors, then either injecting the dependencies they require using a library like Dagger or Koin, or simply initializing them inside the Fragment at some point before they’re used.

If your Fragment has a default empty constructor, there’s no need to use a FragmentFactory. If however, your Fragment takes in arguments in its constructor, a FragmentFactory must be used, otherwise a Fragment.InstantiationException will be thrown, since the default FragmentFactory that will be used will not know how to instantiate an instance of your Fragment.

How to use a Fragment and a FragmentFactory hand in hand?

TL;DR Add the FragmentFactory as described above, then add the Fragment as you would usually do.

As mentioned above, as long as the FragmentFactory is set before the Fragment needs to be created, it will be used to instantiate it. This means that a custom FragmentFactory can be used when adding Fragments:

  • Statically with the fragment tag <fragment> and FragmentContainerView.
Declaring a Fragment to attach using a FragmentContainerView.
Setting the FragmentFactory to use to initialize the Fragment declared in the FragmentContainerView.
  • Dynamically with the overloaded FragmentTransaction#add() methods that take as input the Fragment class or the Fragment instance.
Setting the FragmentFactory and adding a Fragment dynamically.

FragmentFactory and nested Fragments

TL;DR Nested Fragments use their parent’s FragmentFactory, unless overridden.

If a parent Fragment contains nested Fragments or multiple levels of nested Fragments, then by default, they all use the same FragmentFactory from the parent Fragment. However, a nested Fragment can override this by calling Fragment#childFragmentManager.fragmentFactory.

NestedFragment is created using parentFragmentFactory, whereas NestedNestedFragment is created using childFragmentFactory.

Conclusion

FragmentFactory now allows Fragment constructor injection, which wasn’t possible for a long time in Android. Furthermore, migrating to it can be done one Fragment at a time, making its adoption relatively easy.

For more on Fragments, check out the resources below.

For more on Java, Kotlin and Android, follow me to get notified when I write new posts, or let’s connect on Github and Twitter!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in ProAndroidDev

The latest posts from Android Professionals and Google Developer Experts.

Responses (10)

What are your thoughts?