In this lesson we learn how to make your Fragment’s component lifecycle match the Jetpack ViewModel lifecycle. This opens up possibilities (including not needing to rely on using ViewModel directly) for retaining state during your Fragment’s “user perceived” lifecycle.
I say “user perceived” because, your user doesn’t care that your Fragment was torn down due to a configuration change. As far as they’re concerned, they are looking at the same screen. I’ve found that the dependencies needed for each screen generally mirror that lifecycle as well.
This strategy is completely optional—use what works best for your use case—however I encourage it if you’re using injected ViewModels. If your dependencies are recreated on config change because you create a new Component, but you’ve already created the ViewModel for that screen, you may end up with mis-matched shared dependencies in injected components outside of your ViewModel.
Thanks for the awesome course,
I have couple of questions which I hope I can get a detailed answer from you:
1- as far as I understand, this approach is suitable for dynamic features, because of the appdeps module, am I right ?
2- What's the difference between ScreenScope and the ActivityScope, I can see that ScreenScope is tied to a viewmodel lifecycle, but can't get the difference between both when used in the flow you mentioned about credit card adding.
3- what if I have a dependency that I want it to be shared between details and home feature, and I don't want to put it in app level, I feel that creating a module like appDeps just for this is a bit overkill, couldn't figure out another way.
4- How to handle the lifecycle of a scope created to live in 2 features? like in question 3. I know we can go singleton or activity level, but can we go a little deeper like managing the scope lifecycle ourselves ?
5- the viewmodel lifecycle is managed by jetpack, if we need to share a viewmodel across fragments, how do we use activityViewModels instead of the viewmodel type?
6- Sorry for the wall of text, and thanks for the great content again.
For the most part, yeah. Later in the course we depend directly on "feature" modules in the app module for determining which Fragment to show, so that would need a slight abstraction, but otherwise these modules are completely independent.
ScreenScope will have scopes that mirror a Fragment's lifecycle, whereas ActivityScope mirrors the Activity lifecycle.
For the banking example, you could have many screens used to complete a transaction, and those could share state in the ActivityScope (data about the transaction you're "building"), but have their own state in the ScreenScope.
That's definitely not overkill! If multiple modules need to depend on something else, it should be its own module.
You can create your own scope. Managing it would be up to you and require manual management since it would be independent of framework object lifecycles. This is a bonus to using Dagger 2 directly, instead of something like Hilt, for example. Complete control to put different scopes between others. Or you could have it completely separate and not, for instance, between the Activity and Screen scopes.
You can get a view model like you would have otherwise. Just use the activity reference available in the Fragment to get a reference to it. The factory should work just fine for Activity scoped view models. Or, don't use ViewModel at all and just create an @ActivityScope injectable object.
You're welcome, and no apologies needed!
I have followed the course to the point where I have to display fake repo data in my home fragment. Unfortunately I keep getting the error below when running the app in the emulator for the first time. What am I doing wrong?
java.lang.ClassCastException: com.ijikod.di.home.HomeComponentKt$inject$1 cannot be cast to com.ijikod.di.home.HomeComponent
Thanks for your reply. Do find below.
Now this is getting a bit embarrassing, lol. Anyway do pull from the repo again as I have update the code to the latest version I have.
Also I have tried invalidating cache as it crashing on line 23 in HomeComponent.kt. Do let me know if I am doing something wrong here.