[英]Problem to resolve Context Injected in BroadcastReceiver using dagger hilt for android
I try to inject a class on a BootReceiver (BroadcastReceiver) class and hilt has some issues to resolve the context.我尝试在 BootReceiver (BroadcastReceiver) 类上注入一个类,但 hilt 有一些问题来解决上下文。 I tried a lot of things and maybe one of you sees what is not correct.
我尝试了很多东西,也许你们中的一个人看到了什么是不正确的。 So here is the code example is failing during compile time:
所以这里的代码示例在编译时失败:
The BootReceiver is defined in AndroidManifest, and will be stated from there: AndroidManifest.xml BootReceiver 在 AndroidManifest 中定义,将从那里声明:AndroidManifest.xml
<receiver android:name="ch.didge.flashcaller.BootReceiver" android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
The class itselfs is defined in BootReceiver.kt类本身在 BootReceiver.kt 中定义
@AndroidEntryPoint
class BootReceiver : BroadcastReceiver() {
@Inject lateinit var flashCallerRepository: FlashCallerRepository
override fun onReceive(context: Context?, intent: Intent?) {
Log.i("BootReceiver", "context: $context intent: $intent")
context?.let {
if (flashCallerRepository.getAutostartService()) {
val i = Intent(context, FlashcallerService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(i)
} else {
context.startService(i)
}
}
} ?: run {
Log.w("BootReceiver", "Context was null not able to start Service")
}
}
}
FlashCallerRepository.kt FlashCallerRepository.kt
class FlashCallerRepository @Inject constructor( var configurationService:
IConfigurationService) {
fun getAutostartService(): Boolean {
return configurationService.getAutostartService()
}
}
I want to inject an interface and making the mapping to the implementation here:我想注入一个接口并在此处映射到实现:
@Module
@InstallIn(ApplicationComponent::class)
object DiFeatureModule {
@Singleton
@Provides
fun provideConfigurationService(@ApplicationContext appContext: Context
): IConfigurationService {
return SharedPreferencesConfigurationService(appContext)
}
}
Unfortunately there is an issue providing the context.不幸的是,提供上下文存在问题。 I'll using hilt version 2.29.1- alpha.
我将使用刀柄版本 2.29.1- alpha。 It seems with my code, hilt is not able to provide the Context (it should provide the Application Context) The funny thing is , I'm injecting the same class (FlashCallerRepository) from my Activity class too, and there it does work like a charm.
我的代码似乎无法提供上下文(它应该提供应用程序上下文)有趣的是,我也从我的 Activity 类中注入了相同的类 (FlashCallerRepository),它确实像魅力。 It seems to be related with the Receiver.
它似乎与接收器有关。
Any Ideas what should be changed?任何想法应该改变什么? Thanks a lot!
非常感谢!
Luke卢克
Here is the detailed compile stacktrace:这是详细的编译堆栈跟踪:
* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task
':app:transformClassesWithAndroidEntryPointTransformForFullRelease'.
at
org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:205)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:203)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:184)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:109)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Caused by: java.lang.RuntimeException: javassist.bytecode.BadBytecode: onReceive (Landroid/content/Context;Landroid/content/Intent;)V in ch.didge.flashcaller.BootReceiver: failed to resolve types
at com.android.builder.profile.Recorder$Block.handleException(Recorder.java:55)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:108)
at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:242)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)
at org.gradle.api.internal.project.taskfactory.IncrementalTaskInputsTaskAction.doExecute(IncrementalTaskInputsTaskAction.java:47)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:42)
at org.gradle.api.internal.project.taskfactory.AbstractIncrementalTaskAction.execute(AbstractIncrementalTaskAction.java:25)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:568)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:553)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:536)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:109)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:276)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:265)
at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$0(ExecuteStep.java:32)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:32)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:63)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:44)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:153)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:67)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:41)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)
at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:92)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:94)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)
at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)
at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)
at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)
at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)
at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)
at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:192)
... 30 more
Caused by: javassist.bytecode.BadBytecode: onReceive (Landroid/content/Context;Landroid/content/Intent;)V in ch.didge.flashcaller.BootReceiver: failed to resolve types
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:119)
at javassist.bytecode.MethodInfo.rebuildStackMap(MethodInfo.java:458)
at dagger.hilt.android.plugin.AndroidEntryPointClassTransformer.transformOnReceive(AndroidEntryPointClassTransformer.kt:237)
at dagger.hilt.android.plugin.AndroidEntryPointClassTransformer.transformClass(AndroidEntryPointClassTransformer.kt:134)
at dagger.hilt.android.plugin.AndroidEntryPointClassTransformer.transformClassToOutput(AndroidEntryPointClassTransformer.kt:106)
at dagger.hilt.android.plugin.AndroidEntryPointClassTransformer.transformFile(AndroidEntryPointClassTransformer.kt:102)
at dagger.hilt.android.plugin.AndroidEntryPointTransform.transformFile(AndroidEntryPointTransform.kt:156)
at dagger.hilt.android.plugin.AndroidEntryPointTransform.transform(AndroidEntryPointTransform.kt:124)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:284)
at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:247)
at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:106)
... 92 more
Caused by: javassist.bytecode.BadBytecode: failed to resolve types
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:177)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:116)
... 102 more
Caused by: javassist.NotFoundException: android.content.Context
at javassist.ClassPool.get(ClassPool.java:430)
at javassist.bytecode.stackmap.TypeData$TypeVar.fixTypes2(TypeData.java:437)
at javassist.bytecode.stackmap.TypeData$TypeVar.fixTypes(TypeData.java:410)
at javassist.bytecode.stackmap.TypeData$TypeVar.dfs(TypeData.java:357)
at javassist.bytecode.stackmap.MapMaker.fixTypes(MapMaker.java:398)
at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:175)
... 103 more
I did found a solution for my situation.我确实找到了适合我情况的解决方案。 Reason is that in my case the BootReceiver seems to be a constellation that won't be supported by hilt, due this BootReceiver will be the starting Point of the Application.
原因是在我的情况下,BootReceiver 似乎是一个不会被 hilt 支持的星座,因为这个 BootReceiver 将成为应用程序的起点。 In my understanding it should not may a difference, because even then an Application Class object should be created which should ramp up the whole dependency tree.
根据我的理解,这应该没有区别,因为即使这样,也应该创建一个应用程序类对象,它应该会增加整个依赖树。
I hope when hilt is leaving alpha, this scenario will be supported too.我希望当 hilt 离开 alpha 时,这种情况也会得到支持。 So here I can show you my solution:
所以在这里我可以向您展示我的解决方案:
class BootReceiver : BroadcastReceiver() {
lateinit var flashCallerRepository: FlashCallerRepository
@EntryPoint
@InstallIn(ApplicationComponent::class)
interface BootReceiverEntryPoint {
fun getflashCallerRepository(): FlashCallerRepository
}
override fun onReceive(context: Context?, intent: Intent?) {
Log.i("BootReceiver", "context: $context intent: $intent")
val entryPoint = EntryPointAccessors.fromApplication(context,
BootReceiverEntryPoint::class.java)
flashCallerRepository = entryPoint.getflashCallerRepository()
context?.let {
if (flashCallerRepository.getAutostartService()) {
val i = Intent(context, FlashcallerService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(i)
} else {
context.startService(i)
}
}
} ?: run {
Log.w("BootReceiver", "Context was null not able to start Service")
}
}
}
My expectation is, that once hilt will work in a way, that I'm able to use injection a BootReceiver like already described in my question above.我的期望是,一旦 hilt 会以某种方式工作,我就可以像上面的问题中已经描述的那样使用注入 BootReceiver。
If someone knows how tho handle in a standard hilt way please let my know.如果有人知道如何以标准刀柄方式处理,请告诉我。 At least i was able to solve my situation.
至少我能够解决我的情况。
I created an issue in the hilt-project: issue in dagger-hilt project我在 hilt-project: issue in dagger-hilt project 中创建了一个问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.