Android + Gradle Modules + Navigation + FragmentFactory + Fragment constructor injection
App structure
Jetpack Navigation library
Fragment
FragmentFactory
@NonNull
public Fragment instantiate(@NonNull ClassLoader classLoader, @NonNull String className) {
try {
Class<? extends Fragment> cls = loadFragmentClass(classLoader, className);
return cls.getConstructor().newInstance();
} catch (e) { ... }
}
Dagger and FragmentFactory
class DaggerFragmentFactory(
private val providers: MutableMap<Class<out Fragment>, Provider<Fragment>>
) : FragmentFactory() {
override fun instantiate(
classLoader: ClassLoader,
className: String
): Fragment {
val fragmentClass = loadFragmentClass(classLoader, className)
val fragment = providers[fragmentClass]?.get()
return requireNotNull(fragment)
}
}
Dagger component
@Component(modules = [...])
interface FeatureComponent {
fun provideFragmentFactory(): Provider<FragmentFactory>
@Component.Factory
interface Factory {
fun create(@BindsInstance ...): FeatureComponent
}
}
DelegateFragmentFactory
class DelegateFragmentFactory(
private val providers: List<() -> FragmentFactory>
) : FragmentFactory() {
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
for (provider in providers) {
try {
return provider.invoke().instantiate(classLoader, className)
} catch (e: Exception) {
// do nothing
}
}
return super.instantiate(classLoader, className)
}
}
Application and Activities