Dagger 2 injection not working

2019-05-06 15:06发布

问题:

The module that proides singletons of Gson, Retrofit and OkHttpClient

@Module
public class MyModule {

    @Provides
    @Singleton
    Gson provideGson() {
        GsonBuilder gsonBuilder = new GsonBuilder();
        return gsonBuilder.create();
    }

    @Provides
    @Singleton
    OkHttpClient provideOkHttpClient() {
        OkHttpClient client = new OkHttpClient();
        return client;
    }

    @Provides
    @Singleton
    Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create(gson))
                .baseUrl(BuildConfig.SERVER_BASE_URL)
                .client(okHttpClient)
                .build();
        return retrofit;
    }
}

The component that allows injecting the Singletons into activity and fragments

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

    void inject(Activity activity);
    void inject(Fragment fragment);
    void inject(Application application);
}

The main application class that builds the component

public class MyApp extends Application{


    private MyComponent component;

    @Inject
    Retrofit retrofit;

    @Override
    public void onCreate() {
        super.onCreate();
        component= DaggerMyComponent.builder()
                .myModule(new MyModule()).build();
        getComponent().inject(this); // inject retrofit here
    }

    public MyComponent getComponent() {
        return component;
    }
}

This is the Fragment where I am trying to inject Retrofit.

public class MyFragment extends Fragment {

    @Inject
    Retrofit retrofit;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        ((MyApp)getActivity().getApplication()).getComponent().inject(this);
      ....

    }
}

In both MyApp and MyFragment the retrofit instance is null.

回答1:

You can inject Activity,Fragment and Application in Same Component.You need to create Separate component for each Activity ,Fragment and Component Like this:

Activiy

Use this component in all your activity:

@Singleton
@Component(modules={MyModule.class})
public interface MyActivityComponent {
    void inject(Activity activity);
    void inject(AnotherActivity activity);
}

Inject in activity like this:

component= DaggerMyActivityComponent.builder()
                .myModule(new MyModule()).build();
        getComponent().inject(this)

Fragment

Use this component in all your fragment:

    @Singleton
    @Component(modules={MyModule.class})
    public interface MyFragmentComponent {

        void inject(Fragment fragment);
        void inject(AnotherFragmen fragment);
    }

Inject in fragment like this:

component= DaggerMyFragmentComponent.builder()
                .myModule(new MyModule()).build();
        getComponent().inject(this)

Application

Use this component in your Application:

    @Singleton
    @Component(modules={MyModule.class})
    public interface MyAppComponent {
        void inject(Application application);
    }

Inject in Application like this:

component= DaggerMyAppComponent.builder()
                .myModule(new MyModule()).build();
        getComponent().inject(this)