匕首注射到工作经理AssistedInject_AppAssistedInjectModule



我想在工作管理器中注入存储库和其他存储库。由于工作管理器是和Android组件,我不能只是在构造中注入东西,但我必须创建一个工厂类。所以我在 Medium 上找到了一个示例,并遵循了它。我有依赖项

// Dagger 2
def dagger_version = '2.24'
implementation "com.google.dagger:dagger-android:$dagger_version"
implementation "com.google.dagger:dagger-android:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version"
annotationProcessor "com.google.dagger:dagger-android-processor:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
// Assisted Injection
def dagger_assist_version = '0.3.3'
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:$dagger_assist_version"
kapt "com.squareup.inject:assisted-inject-processor-dagger2:$dagger_assist_version"

然后我有工作管理器模块,我在其中绑定了我的工人类工厂

@Module
interface WorkManagerModule {
@Binds
@IntoMap
@WorkManagerKey(FileSplitter::class)
fun bindImageSplitterWorker(factory: FileSplitter.Factory): ChildWorkerFactory
}

工作管理器组件


@Component(modules = [AppAssistedInjectModule::class, WorkManagerModule::class])
interface WorkManagerComponent {
fun factory(): AppWorkerFactory
}

和工厂

class AppWorkerFactory @Inject constructor(
private val workerFactories: Map<Class<out CoroutineWorker>,
@JvmSuppressWildcards Provider<ChildWorkerFactory>>
) : WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): CoroutineWorker? {
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)
}
}

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

以及我想在其中构建 DagggerComponent 的应用程序类

val factory: AppWorkerFactory = DaggerWorkManagerComponent.create().factory()
WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(factory).build())

所以我的工作管理器类就像

class FileSplitter @AssistedInject constructor(
@Assisted private val appContext: Context,
@Assisted private val params: WorkerParameters,
@Assisted private val messagesRepository: MessagesRepository
) : CoroutineWorker(appContext, params) {
override val coroutineContext = Dispatchers.IO
override suspend fun doWork(): Result = coroutineScope {
... CODE...
Result.success()
}
@AssistedInject.Factory
interface Factory : ChildWorkerFactory
companion object {
private const val TAG = "ImageSplitterWorker"
}
}

在构建项目中,我收到多个错误。但前两个错误似乎是真正的问题。我不明白它可能出了什么问题。他们来了。

...di/modules/AppAssistedInjectModule.java:7: error: cannot find symbol
@dagger.Module(includes = {AssistedInject_AppAssistedInjectModule.class})
^
symbol: class AssistedInject_AppAssistedInjectModule
..di//modules/AppAssistedInjectModule.java:8: error: [ComponentProcessor:MiscError] dagger.internal.codegen.ComponentProcessor was unable to process this class because not all of its dependencies could be resolved. Check for compilation errors or a circular dependency with generated code.
public abstract class AppAssistedInjectModule {

嗯....似乎Dagger2注入工作管理器尚无法完成。Github中有一个悬而未决的问题。任何知道的人请告知!!

解决方案是下面的代码(每个部分都是我的项目的单独文件(

Gradle 进口

// Dagger 2
def dagger_version = '2.27'
implementation "com.google.dagger:dagger-android:$dagger_version"
implementation "com.google.dagger:dagger-android:$dagger_version"
implementation "com.google.dagger:dagger-android-support:$dagger_version"
kapt "com.google.dagger:dagger-compiler:$dagger_version"
kapt "com.google.dagger:dagger-android-processor:$dagger_version"
// Assisted Injection
def dagger_assist_version = '0.5.2'
compileOnly "com.squareup.inject:assisted-inject-annotations-dagger2:$dagger_assist_version"
kapt "com.squareup.inject:assisted-inject-processor-dagger2:$dagger_assist_version"

工人类


class FileSplitterWorker @AssistedInject constructor(
@Assisted private val appContext: Context,
@Assisted private val params: WorkerParameters,
private val messagesRepository: MessagesRepository
) : CoroutineWorker(appContext, params) {
override suspend fun doWork(): Result {
// Do Work with messageRepository
return Result.success()
}
@AssistedInject.Factory
interface Factory : ChildWorkerFactory
}

创建此接口

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

和工人的工厂课程

class AppWorkerFactory @Inject constructor(
private val workerFactories: Map<Class<out CoroutineWorker>, @JvmSuppressWildcards Provider<ChildWorkerFactory>>
) : WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): CoroutineWorker? {
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)
}
}

dagger的应用组件应该像

@Singleton
@Component(
modules = [
AndroidInjectionModule::class,
AndroidSupportInjectionModule::class,
AppAssistedInjectModule::class,
WorkManagerModule::class,
etc etc...
]
)
interface AppComponent {
fun inject(application: MyApplication)
fun workerFactory(): AppWorkerFactory
@Component.Factory
interface Factory {
fun withContext(@BindsInstance application: MyApplication): AppComponent
}
}

@Module(includes = [AssistedInject_AppAssistedInjectModule::class])
@AssistedModule
interface AppAssistedInjectModule

工作器模块应该是和接口


@Module(includes = [RepositoryModule::class, etc etc])
interface WorkManagerModule {
@Binds
@IntoMap
@WorkManagerKey(FileSplitterWorker::class)
fun bindFileSplitterWorker(factory: FileSplitterWorker.Factory): ChildWorkerFactory
}

和应用程序类

override fun onCreate() {
super.onCreate()
instance = this

val daggerAppComponent = DaggerAppComponent.factory().withContext(this)
daggerAppComponent.inject(this)
val factory: AppWorkerFactory = daggerAppComponent.workerFactory()
WorkManager.initialize(this, Configuration.Builder().setWorkerFactory(factory).build())
}
companion object {
private lateinit var instance: MyApplication
}

最后,您应该在应用程序标记中将工作管理器声明到清单

<provider
android:name="androidx.work.impl.WorkManagerInitializer"
android:authorities="${applicationId}.workmanager-init"
android:exported="false"
tools:node="remove" />

相关内容

  • 没有找到相关文章

最新更新