如何使用Retrofit解决多个API端点问题?
在我的Android项目中,我为一个 API端点使用了以下Retrofit ApiModule
。 请注意,我使用Dagger注入依赖项。
@Module(
complete = false,
library = true
)
public final class ApiModule {
public static final String PRODUCTS_BASE_URL = "https://products.com";
@Provides
@Singleton
Endpoint provideEndpoint() {
return Endpoints.newFixedEndpoint(PRODUCTS_BASE_URL);
}
@Provides
@Singleton
ObjectMapper provideObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(
PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
return objectMapper;
}
@Provides
@Singleton
RestAdapter provideRestAdapter(
Endpoint endpoint, ObjectMapper objectMapper) {
return new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.NONE)
.setEndpoint(endpoint)
.setConverter(new JacksonConverter(objectMapper))
.build();
}
@Provides
@Singleton
ProductsService provideProductsService(RestAdapter restAdapter) {
return restAdapter.create(ProductsService.class);
}
}
现在,还有另一个我想与之通信的API (例如"http://subsidiaries.com"
)。 是否可以在重新使用ObjectMapper
和ApiModule
同时扩展给定的RestAdapter
? 或者我应该不扩展它? 我已经尝试复制模块。 但是这涉及到我必须复制Endpoint
, ObjectMapper
和... RestAdapter
有一个私人构造RestAdapter
- 所以我不能。
我想你可以使用Named
注释:
@Module(
complete = false,
library = true
)
public final class ApiModule {
public static final String PRODUCTS_BASE_URL = "https://products.com";
public static final String SUBSIDIARIES_BASE_URL = "https://subsidiaries.com";
public static final String PRODUCTS = "products";
public static final String SUBSIDIARIES = "subsidiaries";
@Provides
@Singleton
@Named(PRODUCTS)
Endpoint provideProductsEndpoint() {
return Endpoints.newFixedEndpoint(PRODUCTS_BASE_URL);
}
@Provides
@Singleton
@Named(SUBSIDIARIES)
Endpoint provideSubsidiariesEndpoint() {
return Endpoints.newFixedEndpoint(SUBSIDIARIES_BASE_URL);
}
@Provides
@Singleton
ObjectMapper provideObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(
PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
return objectMapper;
}
@Provides
@Singleton
@Named(PRODUCTS)
RestAdapter provideProductsRestAdapter(@Named(PRODUCTS) Endpoint endpoint, ObjectMapper objectMapper) {
return newRestAdapterBuilder(objectMapper)
.setEndpoint(endpoint)
.build();
}
@Provides
@Singleton
@Named(SUBSIDIARIES)
RestAdapter provideSubsidiariesRestAdapter(@Named(SUBSIDIARIES) Endpoint endpoint, ObjectMapper objectMapper) {
return newRestAdapterBuilder(objectMapper)
.setEndpoint(endpoint)
.build();
}
@Provides
@Singleton
@Named(PRODUCTS)
ProductsService provideProductsService(@Named(PRODUCTS) RestAdapter restAdapter) {
return restAdapter.create(ProductsService.class);
}
@Provides
@Singleton
@Named(SUBSIDIARIES)
ProductsService provideSubsidiariesService(@Named(SUBSIDIARIES) RestAdapter restAdapter) {
return restAdapter.create(ProductsService.class);
}
private RestAdapter.Builder newRestAdapterBuilder(ObjectMapper objectMapper) {
return new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.NONE)
.setConverter(new JacksonConverter(objectMapper));
}
}
现在,在注入ProductsService
任何地方,您都需要使用@Named(PRODUCTS)
或@Named(SUBSIDIARIES)
注释依赖项,具体取决于您需要的变体。 当然,您也可以创建自己的自定义注释并使用它们来代替@Named
注释。 请参阅“限定词”。
为了扁平化你的模块,你可以将RestAdapter的创建移动到provide*Service()
方法中,并去除provide*RestAdapter()
方法。 当然,除非需要RestAdapter作为模块外的依赖项。