Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Dagger 2 and constructor injection

I'm new to dagger and my constructor/method injection doesn't seem to work. Doesn't work meaning the injected fields are still requested.

This is my code:

@Module
public class AppContextModule {

    private final Context appContext;

    public AppContextModule(Context appContext) {
        this.appContext = appContext;
    }

    @Singleton
    @Provides
    public Context getAppContext() {
        return appContext;
    }

}

@Singleton
@Component(modules = {AppContextModule.class})
public interface MyComponent {

    void inject(ActivitiesLifeCycleListener obj);

    void inject(WebViewManager obj);

    Context context();

}

public final class MyClass {

    private final WeakReference<Context> mAppContext;

    @Inject
    public MyClass(Context context)  {
        this.mAppContext = context
    }

}

public class MyActivity extends BaseActivity {

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

        MyClass my = new MyClass(); // The IDE requests context!

    }

}

"MyClass" still requires "Context" although I used the "@Inject" annotation above the constructor. What am I missing?

Do I even need to expose my Context?

Thanks.

like image 515
EladB Avatar asked May 16 '16 12:05

EladB


People also ask

What is constructor Injection in Dagger?

Note: The Dagger basics page covers how to use the Dagger @Inject annotation in constructors. This annotation tells Dagger how to create instances of a class. Instead of creating the dependencies an activity requires in the onCreate() method, you want Dagger to populate those dependencies for you.

What is inject annotation in Dagger?

With the @Inject annotation on the constructor, we instruct Dagger that an object of this class can be injected into other objects. Dagger automatically calls this constructor, if an instance of this class is requested.

Does Dagger 2 use reflection?

Dagger is a compile-time framework for dependency injection. It uses no reflection or runtime bytecode generation, does all its analysis at compile-time, and generates plain Java source code.

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

Well...you declare your constructor

public MyClass(Context context)  {
    this.mAppContext = context
}

And then call it without any parameters

MyClass my = new MyClass(); // The IDE requests context!

Why do you think this should work? This is plain java, no dagger involved, and you are trying to create some new object without supplying the arguments needed.


Dagger is no magic that changes how java works. To use constructor injection you have to actually use Dagger to inject your fields.

public class MyActivity extends BaseActivity {

    @Inject
    MyClass mMyClass; // mark field for injection

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

        // todo ... create component

        component.inject(this); // inject fields
    }

}

Given that you provide a Context somewhere (you'll get a Context must be provided... compile error if it is not) dagger will then inject your activity with MyClass by calling inject—no magic. The inject method will assign the object to your field.


Constructor injection only means that you don't have to use a module and include a method to provide the object. It does not just magically create objects out of thin air or change the way constructors work.

like image 175
David Medenjak Avatar answered Oct 06 '22 04:10

David Medenjak