使用 WorkManager 和 Dagger-Hilt 时无法实例化工作线程错误

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

我在我的应用程序中使用 Dagger Hilt 进行 DI。每当我尝试在构造函数中注入自己的依赖项时,WorkManager 都无法初始化。但当我删除自己的依赖项时它会起作用。

我为 DI 设置了工人类别,如下所示:

UploadTripsWorker 类:

import android.content.Context
import android.util.Log
import androidx.hilt.work.HiltWorker
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.myapp.app.di.ChildWorkerFactory
import com.myapp.app.repo.UserRepositoryInterface
import com.myapp.app.repo.local.LocalDriverRepositoryInterface
import com.google.firebase.auth.FirebaseAuth
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject

@HiltWorker
class UploadTripsWorker @AssistedInject constructor(
    @Assisted appContext: Context,
    @Assisted workerParams: WorkerParameters,
    private val userRepository: UserRepositoryInterface,
    private val localUserRepository: LocalDriverRepositoryInterface,
    private val auth: FirebaseAuth
) : CoroutineWorker(appContext, workerParams) {

    @AssistedFactory
    interface Factory : ChildWorkerFactory {
        override fun create(appContext: Context, params: WorkerParameters): UploadTripsWorker
    }

//doWork logic here

}

MyWorkerFactory 类:

import android.content.Context
import androidx.work.ListenableWorker
import androidx.work.WorkerFactory
import androidx.work.WorkerParameters
import javax.inject.Inject
import javax.inject.Singleton
import javax.inject.Provider

@Singleton
class MyWorkerFactory @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接口:

import android.content.Context
import androidx.work.WorkerParameters
import com.myapp.app.workers.UploadTripsWorker

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

WorkerBindingModule接口:

import com.myapp.app.workers.UploadTripsWorker
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.IntoMap

@Module
@InstallIn(SingletonComponent::class)
interface WorkerBindingModule {
    @Binds
    @IntoMap
    @WorkerKey(UploadTripsWorker::class)
    fun bindUploadTripsWorker(factory: UploadTripsWorker.Factory): ChildWorkerFactory
}

注解类WorkerKey:

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

@MapKey
annotation class WorkerKey(val value: KClass<out ListenableWorker>)

在AppModule内部,我提供了必要的依赖项:

@Module
@InstallIn(SingletonComponent::class)
object AppModule {
    @Singleton
    @Provides
    fun provideFirebaseAuth(): FirebaseAuth = FirebaseAuth.getInstance()

    @Singleton
    @Provides
    fun provideNormalUserRepository(db: FirebaseFirestore, storage: FirebaseStorage, auth: FirebaseAuth) = UserRepository(db,storage, auth) as UserRepositoryInterface

    @Singleton
    @Provides
    fun provideLocalDriverRepository(driverDao: DriverDao): LocalDriverRepositoryInterface {
        return LocalDriverRepository(driverDao)
    }
}

在清单中我使用:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />

这是我的应用程序类:

@HiltAndroidApp
class MyAppApplication : Application(), Configuration.Provider {
    @Inject
    lateinit var workerFactory: HiltWorkerFactory

    override val workManagerConfiguration: Configuration
        get() = Configuration.Builder()
            .setWorkerFactory(workerFactory)
            .build()

    override fun onCreate() {
        super.onCreate()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "location",
                "Location Service",
                NotificationManager.IMPORTANCE_LOW
            )
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notificationManager.createNotificationChannel(channel)
        }

        WorkManager.initialize(this, workManagerConfiguration)
    }
}

每当我从

userRepository
的构造函数中删除
localUserRepository
auth
UploadTripsWorker
时,worker 都会正常启动。 所以这没有问题:

@HiltWorker
class UploadTripsWorker @AssistedInject constructor(
    @Assisted appContext: Context,
    @Assisted workerParams: WorkerParameters
) : CoroutineWorker(appContext, workerParams) {

但是当我添加:

private val userRepository: UserRepositoryInterface,
private val localUserRepository: LocalDriverRepositoryInterface,
private val auth: FirebaseAuth

对于

UploadTripsWorker
的构造函数,它不起作用。抛出错误:

Could not instantiate com.myapp.app.workers.UploadTripsWorker (Ask Gemini)
 java.lang.NoSuchMethodException: com.myapp.app.workers.UploadTripsWorker.<init> [class android.content.Context, class androidx.work.WorkerParameters]
    at java.lang.Class.getConstructor0(Class.java:3325)
    at java.lang.Class.getDeclaredConstructor(Class.java:3063)
    at androidx.work.WorkerFactory.createWorkerWithDefaultFallback(WorkerFactory.java:94)
    at androidx.work.impl.WorkerWrapper.runWorker(WorkerWrapper.java:243)
    at androidx.work.impl.WorkerWrapper.run(WorkerWrapper.java:144)
    at androidx.work.impl.utils.SerialExecutorImpl$Task.run(SerialExecutorImpl.java:96)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
    at java.lang.Thread.run(Thread.java:1012)
Could not create Worker com.myapp.app.workers.UploadTripsWorker

在我的gradle中:

//Dagger-Hilt
implementation "com.google.dagger:hilt-android:2.49"
kapt "com.google.dagger:hilt-compiler:2.44"
implementation 'androidx.hilt:hilt-common:1.2.0'
implementation 'androidx.hilt:hilt-work:1.2.0'

//Work
implementation "androidx.work:work-runtime-ktx:2.9.0"
plugins {
    id 'kotlin-kapt'
    id 'com.google.dagger.hilt.android'
}
android kotlin dagger-2 dagger-hilt android-workmanager
1个回答
0
投票

我通过将

kapt("androidx.hilt:hilt-compiler:1.2.0")
添加到我的 build.gradle(Module) 文件中解决了这个问题。所以仅仅
kapt "com.google.dagger:hilt-compiler:2.44"
还不够,我们两者都需要。

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