Sagar Suri
03/19/2020, 2:54 AM@Singleton
and @Inject
inside the code instead of Module
?
I have a personal opinion of creating Modules
and defining all my dependencies there instead of marking classes with the above annotations?
Reason being:
1. It help me understand the dependencies and configurations from a single file i.e Module
.
2. It avoid mixing code with configuration(annotations).
What are your opinion on this?
I don’t prefer the following code:
@Module
class BookingDatabaseModule {
@Provides
fun provideBookingDao(database: BookingDatabase) = database.bookingDao()
}
Following is my preferred way of doing it:
@Module
class BookingDatabaseModule {
@Provides
@Singleton
fun provideDatabase(context: Context) = BookingDatabase.newInstance(context)
@Provides
fun provideBookingDao(database: BookingDatabase) = database.bookingDao()
}
What are your opinions?Ianmedeiros
03/24/2020, 2:06 AMColton Idle
03/29/2020, 5:17 PMSlackbot
04/14/2020, 5:06 AMColton Idle
04/24/2020, 12:51 AMJoan Colmenero
04/30/2020, 11:12 AMjava.lang.RuntimeException: android.app.Application does not implement dagger.android.HasAndroidInjectorAny idea, why? It only happens with UI tests, the app runs and everything is injected correctly.
Archie
05/19/2020, 11:08 AMrkeazor
05/20/2020, 1:14 AMJoan Colmenero
05/20/2020, 3:21 PMJoan Colmenero
05/20/2020, 10:34 PMColton Idle
05/27/2020, 3:26 AMColton Idle
05/27/2020, 6:40 AMNicholas Doglio
05/28/2020, 12:48 AMColton Idle
06/06/2020, 1:41 PMbuilder()
method isn't available on MyAppComponent. Anyone have any ideas? The readme doesn't say that I need to change anything. Opened an issue here as well https://github.com/JakeWharton/dagger-reflect/issues/191
EDIT 1: I did find this issue (https://github.com/JakeWharton/dagger-reflect/issues/145) which seems similar, but it doesn't really have a solution? The last semi-helpful response there is to use @Component.Factory
but I'm not sure how that helps. Android Dagger guide doesn't talk about that at all, which just makes it weird that dagger reflect doesn't work with a "typical"/basic dagger setup.
EDIT 2: Also found this https://github.com/JakeWharton/dagger-reflect/issues/4 where Jake says "in general you should refactor to @BindsInstance
and stateless modules."
Maybe that's my solution? But how do I move my simple setup to "BindsInstance and stateless modules". That's going wayy over my head. In the same comment JW seems to mention that Builder() should also already work? Sorry for being a dagger noob herecarlos cdmp
06/08/2020, 11:59 AMColton Idle
06/10/2020, 12:14 AM.create()
which is the url that my networkModule needs.
java
public interface AppComponent {
@Component.Factory
interface Factory {
AppComponent create(@BindsInstance @Named("url") String url);
}
}
This is my networkModule.
kotlin
@Module
class NetworkModule @Inject constructor(@Named("url") val url: String) {...}
I get this dagger error:
error: @Component.Factory method is missing parameters for required modules or components: [com.myapp.internal.NetworkModule]Ideas? Looks like my BindsInstance should satisfy my networkModule.
rattleshirt
06/11/2020, 11:37 AM@InstallIn
work inside gradle submodules? Would you need a sub component per module? I couldn’t find anything in the official doc regarding this.Thomas
06/11/2020, 4:54 PM@InstallIn(FragmentComponent::class)
@Module
object MyFragmentModule {
@Provides
@FragmentScope
internal fun providesViewModel(
fragment: MyFragment,
anotherDependency: Dependency
) = MyViewModel(
fragment.requireArguments().getString("argument"),
anotherDependency
)
}
@AndroidEntryPoint
class MyFragment : Fragment() {
// ...
}
However, this does not appear to work as it shows the following error when building:
error: [Dagger/MissingBinding] com.myapp.MyFragment cannot be provided without an @Inject constructor or an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
Am I doing something wrong? This worked fine without Hilt when using Dagger Android.Marco Righini
06/12/2020, 2:05 PMArchie
06/13/2020, 2:57 PMFragmentFactory
with Hilt. It seems that Hilt
works almost the same way as dagger-android
(please correct me if im wrong) and so, using FragmentFactory
is really hard. Can anyone guide me please.Archie
06/14/2020, 9:06 AMActivityRetainedComponent
vs ActivityComponent
??Ahmed Ibrahim
06/15/2020, 10:03 AMbindsMethod does not represent a type element
issues when started migrating to Hilt? It never popped up before 😕
Caused by: java.lang.IllegalArgumentException: bindsDateFormatter(com.example.date.SalesDateFormatter) does not represent a type element
at dagger.shaded.auto.common.MoreElements$CastingElementVisitor.defaultAction(MoreElements.java:395)
at dagger.shaded.auto.common.MoreElements$CastingElementVisitor.defaultAction(MoreElements.java:386)
at com.sun.tools.javac.code.Symbol$MethodSymbol.accept(Symbol.java:1644)
at dagger.shaded.auto.common.MoreElements.asType(MoreElements.java:128)
at dagger.internal.codegen.validation.TypeCheckingProcessingStep.lambda$process$0(TypeCheckingProcessingStep.java:51)
at com.google.common.collect.RegularImmutableMap.forEach(RegularImmutableMap.java:185)
at dagger.internal.codegen.validation.TypeCheckingProcessingStep.process(TypeCheckingProcessingStep.java:48)
at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:104)
at dagger.internal.codegen.ModuleProcessingStep.process(ModuleProcessingStep.java:59)
And it is just bound using a simple @Binds
@Binds
abstract fun bindsDateFormatter(it: SalesDateFormatter): DateFormatter
deviant
06/15/2020, 1:07 PMManuel Vivo
06/18/2020, 7:39 PMRafal
06/20/2020, 8:12 AMOne of the downsides of a single binding key space is that it can be extra work to place restrictions on code usage (e.g. if one feature shouldn't use bindings from another feature). For this we generally recommend using qualifier annotations that are restricted visibility or using an SPI plugin to enforce separation of code.
I can’t find any info about this SPI plugin. Can anyone point me where I can read about this?Mikael Alfredsson
06/20/2020, 9:06 AM@Provides
@Singleton
fun providesMessageCenter(): MessageCenter = MessageCenter()
for me, this seems to be quite unnecessary and I guess I could annotate the MessageCenter
class directly instead to get it into the graph. Whats the best way of doing this (or is the best way to keep it as it is?)gumil
06/20/2020, 4:58 PMdeviant
06/23/2020, 12:53 PMKayCee
06/29/2020, 4:42 AM@Provides
@Singleton
fun provideMediaPlayer(): MediaPlayer {
return MediaPlayer.create(applicationContext, R.raw.sample)
}
//AppComponent
@Component(modules = [AppModule::class])
@Singleton
interface AppComponent {
fun inject(activity: MainMusicActivity)
fun inject(fragment: FeaturedFragment)
fun inject(fragment: MyMusicFragment)
}
This is inject in fragment, I try both @Inject and @Inject set
@Inject
lateinit var mediaPlayer: MediaPlayer
My question is am I using dagger correctly? Or is there any better way for getting singleton instance of media player with these view pager fragmentsRafal
07/03/2020, 2:20 PMFragmentContextWrapper
so calling any .context
on any view that is in the fragment returns FragmentContextWrapper
instead of an Activity
. We have a Context
extension:
fun Context.navigateWithDirections(
navDirections: NavDirections,
navOptions: NavOptions? = NavOptions.Builder()
.setEnterAnim(R.anim.nav_default_enter_anim)
.setExitAnim(R.anim.nav_default_exit_anim)
.setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
.setPopExitAnim(R.anim.nav_default_pop_exit_anim)
.build()
) {
(this as? Activity)?.findNavController(R.id.nav_host_fragment)?.navigate(navDirections, navOptions)
}
and this (this as? Activity)?
check doesn’t pass cause there is FragmentContextWrapper
. In the docs I see
* Do not use except in Hilt generated code!
So my question is. Is there any other way I can get the activity context instead of this wrapper?Rafal
07/03/2020, 2:20 PMFragmentContextWrapper
so calling any .context
on any view that is in the fragment returns FragmentContextWrapper
instead of an Activity
. We have a Context
extension:
fun Context.navigateWithDirections(
navDirections: NavDirections,
navOptions: NavOptions? = NavOptions.Builder()
.setEnterAnim(R.anim.nav_default_enter_anim)
.setExitAnim(R.anim.nav_default_exit_anim)
.setPopEnterAnim(R.anim.nav_default_pop_enter_anim)
.setPopExitAnim(R.anim.nav_default_pop_exit_anim)
.build()
) {
(this as? Activity)?.findNavController(R.id.nav_host_fragment)?.navigate(navDirections, navOptions)
}
and this (this as? Activity)?
check doesn’t pass cause there is FragmentContextWrapper
. In the docs I see
* Do not use except in Hilt generated code!
So my question is. Is there any other way I can get the activity context instead of this wrapper?streetsofboston
07/03/2020, 2:27 PM.baseContext
(if that is the correct name) until that context is Activity
.jw
07/03/2020, 3:55 PMandroid:theme
attribute or simply using a ContextWrapper
in a view before inflating children would break that assumption. You've always needed to perform a walk up the context hierarchy for accurate results, and you may never even reach an activity if the view is hosted in something like a floating window.harry.singh
07/03/2020, 4:21 PMgetContext()
and getActivity()
in a fragment?