Dagger 2 does not inject my Object but can be obta

2019-07-14 02:07发布

问题:

I have my component like

@GithubListActivityScope
@Component(modules = { GithubListActivityModule.class,GlideActivityModule.class })
public interface GithubListActivityComponent {

GithubUserListAdapter githubUserListAdapter ( );
RequestManager requestManager();
LinearLayoutManager linearLayoutManager();

}

And I have a module like this :

@Module
public class GithubListActivityModule {
private final Activity githubListActivity;


public GithubListActivityModule ( Activity activity ) {
    this.githubListActivity = activity;

}

@Provides
@GithubListActivityScope
Activity activity ( ) {
    return this.githubListActivity;
}

@Provides
@GithubListActivityScope
public LinearLayoutManager linearLayoutManager(Activity activity){
    return  new LinearLayoutManager ( activity );
}
}

Problem : I have treid to inject LinearLayout manager like this :

@GithubListActivityScope
@Inject
LinearLayoutManager linearLayoutManager;  

While my Component is built like this :

githubListActivityComponent = DaggerGithubListActivityComponent.builder ()
            .githubListActivityModule ( new GithubListActivityModule ( this ) )
            .build ();

my Linear Layout manager does not get instantiated. But when I manually do

 linearLayoutManager = githubListActivityComponent.linearLayoutManager ();

It works fine. Where am I going wrong?

回答1:

Everywhere that I am passing Activity , I should pass exactly the same class Name (not its parent) So once edited every parameters and return types that were "Activity" into "GithubListActivity" and then added

void inject( GithubListActivity activity);

inside the component class

then injected "GithubListActivity" like this :

DaggerGithubListActivityComponent.builder ()
            .githubListActivityModule ( new GithubListActivityModule ( this ) )
            .build ().inject ( this );

Then the codes worked for me ..

Lesson :
1. Define inject method and Inject the current Activity

2. Use exactly the same type of object (not the parent ) in this case use "GithubListActivity" instead of just activity.



回答2:

Dagger 2 does not inject fields automatically. It can also not inject private fields. If you want to use field injection you have to define a method in your @Component interface which takes the instance into which you want to inject as parameter (From - http://www.vogella.com/tutorials/Dagger/article.html#special-treatment-of-fields-in-dagger)

Suppose you have a fragment or Activity into which you want to inject these dependencies, then do something like this -

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ((YouApplicationClass) getActivity().getApplication()).getmComponent().inject(this);
}

Let your Application class be like this -

public class YourApplicationClass extends MultiDexApplication {

    private static final String TAG = v.class.getSimpleName();

    private YourComponent mComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        mComponent = DaggerYoutComponent.builder()
                .yourModule(new YourModule(this))
                .build();
    }

    public YourComponent getmComponent() {
        return mComponent;
    }

   .... lots of other code
}

and your component class be something like this -

//@Singleton
@Component(modules = {YourModule.class})
public interface YourComponent {

    void inject(Fragment yourFragment); //the parameter can be any class who is invoking this method i.e. Passing the reference to itself

   ..lots of other code
}