Oussaki
Oussaki

Reputation: 1649

How to pass the current activity to be Injected to an Object in Dagger2

Let's say I have a class A defined like this:

class A {

    Activity c;

    public A(Activity c) {
        this.c = c;
        // do something
    }

    public void dosomething() { }

}

And I have an Activity defined like this:

public class MyActivity extends AppCompatActivity {

    @Inject A myObject;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myObject.dosomething();
    }
}

How can I provide the current activity to my object?

Upvotes: 3

Views: 2190

Answers (1)

Reinstate Monica
Reinstate Monica

Reputation: 2798

You have to make the activity available to the component responsible for constructing myObject. One way to do that is to create an ActivityScope:

@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ActivityScope {
}

Within this scope, you create a component with an inject() method for injecting the Activity's fields.

Note that you can add a dependency on a wider-scoped component if you want that component's object graph available in your MyActivityComponent. Here, I made it depend on a class named ApplicationComponent.

@ActivityScope
@Component(
        dependencies = {ApplicationComponent.class}, 
        modules = { MyActivityModule.class}
)
public interface MyActivityComponent {

    void inject(MyActivity myActivity);

}

The component has a module that provides the MyActivity instance.

@Module
public class MyActivityModule {

    private final MyActivity myActivity;

    public MyActivityModule(MyActivity myActivity) {
        this.myActivity = myActivity;
    }

    @Provides
    @ActivityScope
    MyActivity provideActivity() {
        return myActivity;
    }

}

In your activity's onCreate(), you can now give this to the module, which makes it available within the ActivityScope.

//Inside your activity's onCreate:
DaggerMyActivityComponent.builder()
        .myActivityModule(new MyActivityModule(this))
        .build()
        .inject(this);

EDIT
In response to your question, you need to annotate the constructor in A with @Inject. This will give Dagger a way to create an instance of it. If that's not possible, you could add a provider method in the module, but it's a bit more work:

//Don't do this if you can annotate the constructor with @Inject.
@Provides
A provideA(MyActivity myActivity) {
    return new A(myActivity);
}

Upvotes: 7

Related Questions