question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Feature request] ContributesAndroidInjector with FragmentFactory lifecycles

See original GitHub issue

DaggerFragment used with ContributesAndroidInjector works fine. However, with the introduction of FragmentFactory, field injection is not needed anymore and constructor injection can be used for fragments. While this works fine, subcomponent lifecycle (w.r.t fragment) is missed and in some cases fragment can stay alive even and reused across back stack navigation (within the same activity instance/parent component).

This request to support some kind of scope/life cycle for multibindings used by the fragment factory injector.

Current:

@Module
abstract class FragmentBindingModule {

   @ContributesAndroidInjector( modules = [MainFragmentModule::class] )
    abstract fun mainFragment() : MainFragment
}

New:

@Module
abstract class FragmentModule {

    @Binds
    @IntoMap
    @FragmentKey( MainFragment::class )
    // Associate MainFragmentModule to fragment lifecycle
    abstract fun bindMainFragmentFragment( fragment: MainFragment) : Fragment
}

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:1
  • Comments:7

github_iconTop GitHub Comments

1reaction
nlgtuankietcommented, May 5, 2019

In a nutshell, you still need to write subcomponent manually. The approaches to perform cotructor injection on Fragment class while still maintain scoping is described here: https://medium.com/@nlg.tuan.kiet/fragmentfactory-and-how-to-maintain-scoping-with-dagger-2-d9d16c892626 Sample project: https://github.com/nlgtuankiet/FragmentFactory

class TasksFragment(
    val viewModelFactory: TasksViewModel.Factory,
    private val messageManager: MessageManager,
    private val tasksController: TasksController,
    private val navigator: TasksNavigator
) : Fragment()
@Subcomponent(
    modules = [
        TasksComponent.Provision::class,
        TasksBindingModule::class
    ]
)
@FragmentScope
interface TasksComponent : FragmentComponent<TasksFragment> {
    @Subcomponent.Factory
    interface Factory : FragmentComponent.Factory<TasksComponent>

    @Module
    object Provision {
        @JvmStatic
        @Provides
        @FragmentScope
        fun fragment(
            holder: Holder<TasksFragment>,
            messageManager: MessageManager,
            viewModelFactory: TasksViewModel.Factory,
            tasksController: TasksController,
            navigator: TasksNavigator
        ) = TasksFragment(
            messageManager = messageManager,
            viewModelFactory = viewModelFactory,
            tasksController = tasksController,
            navigator = navigator
        ).also { holder.instance = it }

        @JvmStatic
        @Provides
        @FragmentScope
        fun holder() = Holder<TasksFragment>()
    }
}
class BaseFragmentFactory(
    private val providers: Map<Class<out Fragment>, @JvmSuppressWildcards Provider<FragmentComponent.Factory<*>>>
) : FragmentFactory() {
    override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
        val fragmentClass = classLoader.loadClass(className)
        return providers.entries.find { it.key.isAssignableFrom(fragmentClass) }
            ?.value?.get()?.create()?.fragment() ?: super.instantiate(classLoader, className)
    }
}
0reactions
TheRepratorcommented, Jun 14, 2020

@nlgtuankiet, i had tried to implement your code, it’ working fine, but when i want to create a new separate component, it give me error,

https://github.com/nlgtuankiet/todo-sample/issues/2,

Raised the issue, please have a look at it

Please find the project link to reproduce the error, https://github.com/TheReprator/BugReproduceFragmentFactory

Read more comments on GitHub >

github_iconTop Results From Across the Web

Ian Lake on Twitter: "Thanks for everyone who came to the ...
[Feature request] ContributesAndroidInjector with FragmentFactory ... The real question here is if Fragment loses its own Lifecycle and exists only when it ...
Read more >
Constructor injection into Fragments with respect of scopes
To be able to inject scoped dependencies into ConstructorInjectionFragment we need to create a subcomponent of the activity component for this ...
Read more >
AndroidX Navigation with Dagger 2 & FragmentFactory
Injecting dependencies into Fragment classes has always been less than ideal (to say the least) when compared to other “regular” classes.
Read more >
Using dagger in multi-module apps : r/androiddev - Reddit
ExoPlayer will be usually constrained to a single feature/module, ... Despite all of this, it doesn't require you to learn any Dagger magic ......
Read more >
Droidcon Italy: Working with Dagger and Kotlin - Speaker Deck
class GameFragmentFactory : FragmentFactory() { override fun ... dagger.android @ContributesAndroidInjector dagger.dev/dev-guide/android ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found