Search code examples
androidkotlinandroid-widgetdagger-2appwidgetprovider

Field injection in AppWidgetProvider in kotlin using dagger 2


I am using dagger2 and kotlin in my project. I have injected activity and viewmodels and now I want to inject appwidgetprovider class for app widgets. I can`t find a way to inject fields in to appwidgetprovider class. Here is my dagger2 implementaion.

this is App Component class

@Singleton
@Component(
    modules = [
        UserInformationModule::class,
        AndroidInjectionModule::class,
        AppModule::class,
        MainActivityModule::class,
        ServiceBuilderModule::class]
)

interface AppComponent {
    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: Application): Builder

          fun build(): AppComponent
        }

    fun inject(application: BaseClass)
}

This is AppModule class

@Module(includes = [ViewModelModule::class, CoreDataModule::class])
class AppModule {

    @Singleton
    @Provides
    fun provideMyMyAppService(
        @MyAppAPI okHttpClient: OkHttpClient,
        converterFactory: MoshiConverterFactory
    ) = provideService(okHttpClient, converterFactory, MyMyAppApi::class.java)

@MyAppAPI
@Provides
fun providePrivateOkHttpClient(
    upstreamClient: OkHttpClient
): OkHttpClient {
    return upstreamClient.newBuilder().build()
}

@Singleton
@Provides
fun provideRemoteDataSource(myMyAppService: MyMyAppApi) = RemoteDataSource(myMyAppService)

@Singleton
@Provides
fun provideDb(app: Application) = AppDatabase.getInstance(app)

//other code

This is Fragment Builder Module

@Suppress("unused")
@Module
abstract class FragmentBuildersModule {
    @ContributesAndroidInjector
    abstract fun homeFragment(): HomeFragment

    @ContributesAndroidInjector
    abstract fun fragHome(): FragHome

    //other code
}

this is my Main Activity Module

@Suppress("unused")
@Module
abstract class MainActivityModule {
    @ContributesAndroidInjector(modules = [FragmentBuildersModule::class])
    abstract fun contributeMainActivity(): HomeActivity

    @ContributesAndroidInjector(modules = [FragmentBuildersModule::class])
    abstract fun contributeSplashActivity(): SplashActivity
}

This is my ViewModel Module

@Suppress("unused")
@Module
abstract class ViewModelModule {
    @Binds
    @IntoMap
    @ViewModelKey(HomeViewModel::class)
    abstract fun bindHomeViewModel(viewModel: HomeViewModel): ViewModel

        ///other code
}

I tried to inject appwidgetprivider class using

AndroidInjection.inject(this)

as I did in Service. But this method only excepts Activity, Fragment, service, broadcast receiver and contentproviders. Any help please.

I am using dagger 2.23.2 and kotlin 1.3.41


Solution

  • Appwidget provicer can be injected the same way a broadcast receiver is injected. By looking at your provided code you can do some thing like this. Create an abstract function

    @ContributesAndroidInjector
    internal abstract fun contributeWidget(): YourWidgetClass
    

    extend your Baseclass with HasBroadcastReceiverInjector and implement broadcastReceiverInjector

    @Inject
        lateinit var broadcastReceiverInjector: DispatchingAndroidInjector<BroadcastReceiver>
    
         override fun broadcastReceiverInjector(): AndroidInjector<BroadcastReceiver> {
            return broadcastReceiverInjector
        }
    

    and fillany inject in the widgetprovider class in onreceive before super call

        AndroidInjection.inject(this, context)