📜 ⬆️ ⬇️

"Dagger-Android & AAC" or "shove un-crammed"

image


Today I would like to talk about Dagger 2 , in particular, about dagger-android , Android Architecture Components , as well as about the problem that I encountered when using them. Probably, the post is not so much informative as philosophical, I immediately ask you not to throw slippers, because there are reasons for creating the post (at least subjective), I will tell about them under the cut.


Long wondered whether to write this post, but the internal balance was shaken, and therefore the post to be.


The thing is this: surely many of you have already used the above tools in your projects, or at least have played with them in order to understand what kind of an animal this is. So I finally came to the conclusion that I should use them in my project.


Now, what I wanted to achieve with these tools:



Now a bit of code for better understanding:


Application
class App : DaggerApplication() { override fun applicationInjector(): AndroidInjector<out App> = DaggerAppComponent.builder().create(this) } 

Appcomponent
 @Singleton @Component(modules = [ (AndroidSupportInjectionModule::class), (AppModule::class), (ActivityBuilder::class) ]) interface AppComponent : AndroidInjector<App> { @Component.Builder abstract class Builder : AndroidInjector.Builder<App>() } 

ActivityBuilder
 @Module abstract class ActivityBuilder { @ActivityScope @ContributesAndroidInjector(modules = [MainActivityModule::class, FragmentProvider::class, RepositoryModule::class]) abstract fun bindMainActivity(): MainActivity } 

RepositoryModule
 @Module class RepositoryModule { @Provides @ActivityScope fun provideSomeDataRepository(socket: SocketService, restApi: RestApi, feedDao: FeedDao, userSettings: UserSettings): SomeDataRepository = SomeDataRepositoryImpl(socket, restApi, feedDao, userSettings) 

Injection ViewModelFactory
  @Inject lateinit var factory: MainViewModelFactory private lateinit var viewModel: MainViewModel viewModel = ViewModelProviders.of(this, factory) .get(MainViewModel::class.java) 

ViewModelFactory
 class MainViewModelFactory @Inject constructor(private val someDataRepository: SomeDataRepository) : ViewModelProvider.Factory{ override fun <T : ViewModel?> create(modelClass: Class<T>): T { if (modelClass.isAssignableFrom(MainViewModel::class.java)) { return MainViewModelImpl(someDataRepository) as T } throw IllegalArgumentException(String.format("%s Not Found", modelClass.simpleName)) } } 

Viewmodel
 class MainViewModelImpl @Inject constructor(someDataRepository: SomeDataRepository) : MainViewModel(), MainViewModel.Input, MainViewModel.Output 

So, about the list, what I wanted to get from all these manipulations.


Everything is good, everything works, only now I noticed one feature (a little later it became obvious): After changing the configuration, Dagger creates dependencies again . If you put a breakpoint on the init block in SomeDataRepositoryImpl, then we will see that when adding a fragment with the same dependency, an instance of the same object that was created when creating the activity (breakpoint did not work) is passed to the fragment. But when the screen is flipped, we will observe the creation of a new object (breakpoint worked), which will not reach the view model, because it already has an instance of this object.


Because of the little development experience with these tools, it was decided to ask other developers for advice, to which I received answers that this situation is the norm, that the garbage collector will cope with this mess, and everything will work fine.


Referring to the title of the post, about "unpicked", it was read somewhere in issues by dagger (not a quote word for word, but the meaning is the same): "You are trying to absorb all the best of these two tools, I do not think that this is possible "


Spoiler

Of course, you can not use the dagger-android, and submit dependencies directly to the view model using AndroidViewModel (application: Applitaction) in passing, but this will not work, because the view model does not need to know about the Application class. For me, still a mystery - why this class exists at all. Can someone explain in the comments?


Summarizing all the above, I have one question: Can I do what I want? Is it possible to get rid of this uncontrollable creation of Dagger objects when changing configuration?


I will be glad to answer in the comments, thank you for your attention.


')

Source: https://habr.com/ru/post/350072/


All Articles