Dagger2, providing Retrofit instances with different URLs

Viewed 4106

Currently I'm using Dagger 2 to inject an instance of Retrofit to use for an api call in a widget. From my understanding, Dagger searches for things to inject using the type, so declaring 2 seperate @Provides Retrofit providesRetrofit() with different names wouldn't work.

Heres my current code:

Module:

@Module
public class ApiModule {

    @Provides
    @Singleton
    GsonConverterFactory provideGson() {
        return GsonConverterFactory.create();
    }

    @Provides
    @Singleton
    RxJavaCallAdapterFactory provideRxCallAdapter() {
        return RxJavaCallAdapterFactory.create();
    }

    @Singleton
    @Provides
    Retrofit providePictureRetrofit(GsonConverterFactory gsonConverterFactory, RxJavaCallAdapterFactory rxJavaCallAdapterFactory) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(MarsWeatherWidget.PICTURE_URL)
                .addConverterFactory(gsonConverterFactory)
                .addCallAdapterFactory(rxJavaCallAdapterFactory)
                .build();
        return retrofit;
    }

....
//Here is the other Retrofit instance where I was wanting to use a different URL.

//    @Singleton
//    @Provides
//    Retrofit provideWeatherRetrofit(GsonConverterFactory gsonConverterFactory, RxJavaCallAdapterFactory rxJavaCallAdapterFactory) {
//        Retrofit retrofit = new Retrofit.Builder()
//                .baseUrl(MarsWeatherWidget.WEATHER_URL)
//                .addConverterFactory(gsonConverterFactory)
//                .addCallAdapterFactory(rxJavaCallAdapterFactory)
//                .build();
//        return retrofit;
//    }
}

Component:

@Singleton
@Component(modules = ApiModule.class)
public interface ApiComponent {

    void inject (MarsWeatherWidget marsWeatherWidget);

}

class extending Application:

public class MyWidget extends Application {

    ApiComponent mApiComponent;

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

        mApiComponent = DaggerApiComponent.builder().apiModule(new ApiModule()).build();
    }

    public ApiComponent getApiComponent() {
        return mApiComponent;
    }
}

and finally where im actually injecting it:

@Inject Retrofit pictureRetrofit;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // There may be multiple widgets active, so update all of them
        mAppWidgetIds = appWidgetIds;
        ((MyWidget) context.getApplicationContext()).getApiComponent().inject(this);
        final int N = appWidgetIds.length;
        for (int i = 0; i < N; i++) {
            updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
        }
    }

......
//use the injected Retrofit instance to make a call

So how can I organize this to give me a seperate Retrofit instance that is built with different URLs for hitting different APIs? Let me know if more info is needed.

2 Answers
Related