Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dagger with Android: How do I inject the current context?

Back when I used RoboGuice, I was able to constructor inject Context into of my classes and RoboGuice would pick the appropriate Context (injects in an Activity would have the Activity context, injects in Application would have the current application context, injects in a Fragment would have the fragment's activity's context, etc...).

Is there a similar method for achieving this with Dagger?

public class Thing {
    @Inject
    public class Thing(Context context){
       // if i'm injected in an Activity, I should be the current activity's context
       // if i'm injected in an Fragment, I should be the fragment's activity context
       // if i'm injected in a Service, I should be the service's context
       // etc...
    }
}
like image 991
Paul Avatar asked May 02 '14 21:05

Paul


People also ask

What is @inject in Android?

You pass the dependencies of a class to its constructor. Field Injection (or Setter Injection). Certain Android framework classes such as activities and fragments are instantiated by the system, so constructor injection is not possible. With field injection, dependencies are instantiated after the class is created.

What is inject annotation in Dagger?

Dagger constructs instances of your application classes and satisfies their dependencies. It uses the javax. inject. Inject annotation to identify which constructors and fields it is interested in. Use @Inject to annotate the constructor that Dagger should use to create instances of a class.

How does a Dagger injection work?

Dagger automatically generates code that mimics the code you would otherwise have hand-written. Because the code is generated at compile time, it's traceable and more performant than other reflection-based solutions such as Guice. Note: Use Hilt for dependency injection on Android.

Is Dagger Android deprecated?

It's officially deprecated and you can pretty much ignore it. Google's framework, which became dominant in Android ecosystem, was originally called Dagger 2. Sometimes we still refer to it as such, but, in most cases, we simply call it Dagger today.


1 Answers

Dagger doesn't know about Android. Or anything, really. If you want to inject something, you have to tell Dagger about it.

You can see an example of how to inject a Context in the examples. In this case, a qualifier is used to differentiate the application one from an activity one.

/**
 * Allow the application context to be injected but require that it be annotated with
 * {@link ForApplication @Annotation} to explicitly differentiate it from an activity context.
 */
@Provides @Singleton @ForApplication Context provideApplicationContext() {
  return application;
}

Edit

No, you cannot inject an unqualified type and have the instance of that type change based on the context in which you are performing injection. Dagger requires that the source of a type is known at compile-time and since object graphs are immutable that source cannot be changed.

The only way to do this is to use a factory which allows you to specify the context with which the object will be created.

public final class ThingFactory {
  private final Foo foo;
  private final Bar bar;

  @Inject public ThingFactory(Foo foo, Bar bar) {
    this.foo = foo;
    this.bar = bar;
  }

  public Thing get(Context context) {
    return new Thing(context, foo, bar);
  }
}
like image 196
Jake Wharton Avatar answered Oct 21 '22 09:10

Jake Wharton