google / dagger

A fast dependency injector for Android and Java.
https://dagger.dev
Apache License 2.0
17.45k stars 2.02k forks source link

Add a Lint check for not calling super.onCreate #1950

Open florianwalther-private opened 4 years ago

florianwalther-private commented 4 years ago

Does Hilt currently not work with Services? I have @AndroidEntryPoint on the Service as well as the Activity/Fragment that starts it. I am trying to field-inject a lateinit var but it stays uninitialized. I heard from a friend that he had the same problem.

Chang-Eric commented 4 years ago

Services should be supported. Can you include some sample code or a reproducible example?

florianwalther-private commented 4 years ago

Thank you for the quick response.

My service has one injected field:

@AndroidEntryPoint
class TimerService : Service() {
    @Inject
    lateinit var repository: TaskRepository
    [...]

The fragment (and it's containing activity) that starts the service is also annotated with @AndroidEntryPoint.

The signature of the Repository looks like this. This class is successfully injected in other places in the app:

@Singleton
class TaskRepository @Inject constructor(private val taskDao: TaskDao) 

The repository inside the service is accessed inside onStartCommand

Is there any more you need?

Chang-Eric commented 4 years ago

Hm, that generally looks right to me. I assume you are using the Gradle plugin since you have other fragments and activities that are working, right?

In any case, to rule out the Gradle plugin being an issue, can you try changing to not using it. For example doing:

@AndroidEntryPoint(Service::class)
class TimerService : Hilt_TimerService() {
...
Chang-Eric commented 4 years ago

Assuming that still has the problem, the next thing to check would be using a debugger to step into Hilt_TimerService.onCreate() where we should be calling inject() to inject the fields.

florianwalther-private commented 4 years ago

Thank you for your response. I found the problem. I have overridden onCreate but did not call super.onCreate() (since this method is empty by default in a Service).

Chang-Eric commented 4 years ago

Thanks, we add @CallSuper to the generated base class but that doesn't do anything when you use the plugin.

I think we'll probably want to add our own lint check for this.

florianwalther-private commented 4 years ago

Sounds like a good idea, thanks!

ZacSweers commented 4 years ago

@CallSuper seems like it should be enough, what would a separate lint check do?

Chang-Eric commented 4 years ago

@ZacSweers The issue is that because of the way the plugin works with last second substituting the base class via bytecode transformation, the base class at compile time is not the class that has the @CallSuper annotation on it.