可以使用匕首设置android workmanager以便将存储库注入android worker中

问题描述 投票:0回答:1

[请查找,匕首2和android workmanager的以下设置有什么问题。

WorkerKey.kt

import androidx.work.ListenableWorker
import dagger.MapKey
import kotlin.reflect.KClass

@MapKey
@Target(AnnotationTarget.FUNCTION)
@Retention(AnnotationRetention.RUNTIME)
annotation class WorkerKey(val value: KClass<out ListenableWorker>)

DaggerWorkerFactory.kt

class DaggerWorkerFactory @Inject constructor(
    private val workerFactories: Map<Class<out ListenableWorker>, @JvmSuppressWildcards Provider<ChildWorkerFactory>>
) : WorkerFactory() {

    override fun createWorker(
        appContext: Context,
        workerClassName: String,
        workerParameters: WorkerParameters
    ): ListenableWorker? {
        val foundEntry =
            workerFactories.entries.find { Class.forName(workerClassName).isAssignableFrom(it.key) }
        val factoryProvider = foundEntry?.value
            ?: throw IllegalArgumentException("Unknown worker class name : $workerClassName")
        return factoryProvider.get().create(appContext, workerParameters)
    }
}

ChildWorkerFactory.kt

import android.content.Context
import androidx.work.ListenableWorker
import androidx.work.WorkerParameters

interface ChildWorkerFactory {
    fun create(appContext: Context, params: WorkerParameters): ListenableWorker
}

WorkerModule.kt

import com.hardik.core.di.ChildWorkerFactory
import com.hardik.core.di.WorkerKey
import com.hardik.spendy.PrepopulateCategoryWorker
import dagger.Binds
import dagger.Module
import dagger.multibindings.IntoMap

@Module
interface WorkerModule {

    @Binds
    @IntoMap
    @WorkerKey(PrepopulateCategoryWorker::class)
    fun bindPrepopulateCategoryWork(factory: PrepopulateCategoryWorker.Factory): ChildWorkerFactory
}

AppComponent.kt

@Singleton
@Component(
    modules = [
        AndroidInjectionModule::class,
        AppModule::class,
        DatabaseModule::class,
        UseCaseModule::class,
        ViewModelModule::class,
        WorkerModule::class,
        ActivityModule::class
    ]
)
interface AppComponent : AndroidInjector<SpendyApplication> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(application: SpendyApplication): Builder

        fun build(): AppComponent
    }

    override fun inject(app: SpendyApplication)
}

PrepopulateCategoryWorker.kt

import android.content.Context
import android.util.Log
import androidx.work.ListenableWorker
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.hardik.core.di.ChildWorkerFactory
import com.hardik.repository.Repository
import javax.inject.Inject
import javax.inject.Provider

class PrepopulateCategoryWorker(
    private val appContext: Context,
    private val workerParams: WorkerParameters,
    private val repository: Repository
) : Worker(appContext, workerParams) {

    override fun doWork(): Result {

        Log.i("Hardik", "Repository injected : $repository")
        return Result.success()
    }

    class Factory @Inject constructor(
        private val repository: Provider<Repository>
    ) : ChildWorkerFactory {

        override fun create(appContext: Context, params: WorkerParameters): ListenableWorker {
            return PrepopulateCategoryWorker(
                appContext,
                params,
                repository.get()
            )
        }
    }
}

MainActivity.kt

class MainActivity : DaggerAppCompatActivity() {

     @Inject
    lateinit var workerFactory: WorkerFactory

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
         WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(workerFactory).build())
    }
}

HomeFragment.kt

private fun startPrepopulate() {
        val request = OneTimeWorkRequestBuilder<PrepopulateCategoryWorker>().build()
        val workManager = WorkManager.getInstance(requireContext())
        workManager.enqueue(request)
    }

错误日志

e: C:\git\Spendy\app\build\tmp\kapt3\stubs\debug\com\hardik\spendy\di\AppComponent.java:8: error: [Dagger/MissingBinding] androidx.work.WorkerFactory cannot be provided without an @Provides-annotated method.
public abstract interface AppComponent extends dagger.android.AndroidInjector<com.hardik.spendy.SpendyApplication> {
                ^
      androidx.work.WorkerFactory is injected at
          com.hardik.spendy.ui.activity.MainActivity.workerFactory
      com.hardik.spendy.ui.activity.MainActivity is injected at
          dagger.android.AndroidInjector.inject(T) [com.hardik.spendy.di.AppComponent ? com.hardik.spendy.di.ActivityModule_ContributeMainActivity.MainActivitySubcomponent]
android dagger-2 dagger android-workmanager
1个回答
0
投票

您必须告诉Dagger如何也注入工人工厂。添加

 @Binds
 fun bindWorkManagerFactory(factory: DaggerWorkerFactory): WorkerFactory

至您的WorkerModule

© www.soinside.com 2019 - 2024. All rights reserved.