1

I'm trying to inject Glide with Dagger.

So I have AppModule:

@Module
class AppModule {

    @Provides
    fun provideRequestOptions(): RequestOptions {
        return RequestOptions()
            .placeholder(R.drawable.white_background)
            .error(R.drawable.white_background)
    }

    @Provides
    fun provideGlideInstance(application: Application, requestOptions: RequestOptions): RequestManager{
        return Glide.with(application).setDefaultRequestOptions(requestOptions)
    }

    @Nullable
    @Provides
    fun provideAppDrawable(application: Application): Drawable? {
        return ContextCompat.getDrawable(application, R.drawable.logo)
    }
}

And AuthActivity:

class AuthActivity : DaggerAppCompatActivity() {
    lateinit var binding: ActivityAuthBinding
    @Inject
    lateinit var logo: Drawable
    @Inject
    lateinit var requestManager: RequestManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityAuthBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setLogo()
        }

    private fun setLogo() {
        requestManager.load(logo).into(binding.loginLogo)
    }
}

provideAppDrawable() in AppModule has to return nullable Drawable?. When I'm trying to build app, Dagger complains about its nullability:

\AppComponent.java:7: error: [Dagger/Nullable] android.graphics.drawable.Drawable is not nullable, but is being provided by @org.jetbrains.annotations.Nullable @androidx.annotation.Nullable @Provides android.graphics.drawable.Drawable com.example.daggercodingwithmitch.di.AppModule.provideAppDrawable(android.app.Application)
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.example.daggercodingwithmitch.BaseApplication> {

First I tried to make logo var in AuthActivity nullable, but lateinit can't be nullable. And if I don't use lateinit and make sth like this: var logo: Drawable? = null I get strange error abount private field injection even though it is not private:

\AuthActivity.java:10: error: Dagger does not support injection into private fields
    private android.graphics.drawable.Drawable logo;

How can I fix it? Thx.

faritowich
  • 67
  • 1
  • 10

3 Answers3

1

You need to mark the field "logo" @Nullable as well.

If a @Provides method is marked @Nullable, Dagger will only allow injection into sites that are marked @Nullable as well. A component that attempts to pair a @Nullable provision with a non-@Nullable injection site will fail to compile.

https://dagger.dev/api/2.28/dagger/Provides.html

Yavor Mitev
  • 1,363
  • 1
  • 10
  • 22
1

Make logo field as nullable. Dagger will not allow to inject nullable object to non nullable field.

 @Inject
 var logo: Drawable?=null

In Java,

@Nullable
@Inject
Drawable logo;
Gowtham K K
  • 3,123
  • 1
  • 11
  • 29
0

Easiest way is to make provideAppDrawable return a Drawable instead of a Drawable? and remove the @Nullable from it. Is there any scenario under which that returns null which isn't a bug? If not, it shouldn't be a nullable variable.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • I can't make it non-nullable because ContextCompat.getDrawable(application, R.drawable.logo) method returns nullable Drawable and there is a type mismatch if I make return type non-nullable. – faritowich Aug 06 '22 at 18:16
  • Use ContextCompat.getDrawable(application, R.drawable.logo)!! to force it to be non-nullable. That's a standard feature of Kotlin- !! turns a nullable reference into a non-nullable one and throws an exception if it's null at runtime – Gabe Sechan Aug 06 '22 at 19:55
  • Return a default if it's null using the elvis operator like a ColorDrawable or something .. or provide a supplier `() -> Drawable?` .. or `!!` and let it throw a runtime error if it's null .. there are multiple options here.. – Mark Aug 06 '22 at 19:55