我的情况我需要更改url dynamicaly,但我不想创建2个改造客户端实例。我试图通过拦截器修改来更改基本URL,但改造stil使用旧值。我做错了什么?
App.java
public class App extends Application {
private static AppComponent appComponent;
@Override
public void onCreate() {
super.onCreate();
appComponent =
DaggerAppComponent
.builder()
.appModule(new AppModule(this))
.build();
}
@NonNull
public static App get(@NonNull Context context) {
return (App) context.getApplicationContext();
}
public static AppComponent getAppComponent() {
return appComponent;
}
}
AppModule.java
@Module
public class AppModule {
private Context context;
public AppModule(Context context) {
this.context = context;
}
@Provides
@Singleton
Context provideContext() {
return context;
}
}
NetModule.java
@Module
public class NetModule {
@Provides
@Singleton
Gson provideGson() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
return gsonBuilder.create();
}
@Provides
@Singleton
MainInterceptor provideMyApiInterceptor() {
return MainInterceptor.get();
}
@Provides
@Singleton
OkHttpClient provideOkhttpClient() {
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(15, TimeUnit.SECONDS);
client.connectTimeout(20, TimeUnit.SECONDS);
return client.build();
}
@Provides
@Singleton
Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl("first.url.com")
.client(okHttpClient)
.build();
}
}
NetComponent.java
@Singleton
@Component(modules = NetModule.class)
public interface NetComponent {
Retrofit getRetrofit();
MainInterceptor getInterceptor();
}
MainInterceptor.class
public class MainInterceptor implements Interceptor {
private static MainInterceptor sInterceptor;
private String mScheme;
private String mHost;
public static MainInterceptor get() {
if (sInterceptor == null) {
sInterceptor = new MainInterceptor();
}
return sInterceptor;
}
private MainInterceptor() {
}
public void setInterceptor(String url) {
HttpUrl httpUrl = HttpUrl.parse(url);
mScheme = httpUrl.scheme();
mHost = httpUrl.host();
}
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
if (mScheme != null && mHost != null) {
HttpUrl newUrl = original.url().newBuilder()
.scheme(mScheme)
.host(mHost)
.build();
original = original.newBuilder()
.url(newUrl)
.build();
}
return chain.proceed(original);
}
}
这是在某个类中初始化组件的代码。
NetComponent component= DaggerNetComponent.create();
DataService service = component.getRetrofit().create(DataService.class);
MainInterceptor interceptor = component.getInterceptor();
interceptor.setInterceptor("second.url.com");
service.getSomeData()
之后,网址仍为“first.url.com”
答案 0 :(得分:2)
简单的方法是使用@Named:
@Provides
@Singleton
@Named("retrofit_1")
Retrofit provideRetrofit1(Gson gson, OkHttpClient okHttpClient) {
return new Retrofit.Builder()
...
.baseUrl("url_1.com")
...;}
@Provides
@Singleton
@Named("retrofit_2")
Retrofit provideRetrofit2(Gson gson, OkHttpClient okHttpClient) {
return new Retrofit.Builder()
...
.baseUrl("url_2.com")
...;}
然后使用相同的@Named:
@Provides
IApi1 provideApi_1(@Named("retrofit_1") RestAdapter adapter){....}
@Provides
IApi2 provideApi_2(@Named("retrofit_2") RestAdapter adapter){....}
答案 1 :(得分:1)
当您提供Retrofit
时,您已经设置了baseUrl" first.url.com"
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl("first.url.com")
.client(okHttpClient) //<------ It not OkHttp with your MainInterCeptor
.build();
有趣的事实是,使用新网址设置的MainInterceptor
与您的Retrofit
无关,因为Retrofit
是使用OkHttp
构建的
@Provides
@Singleton
OkHttpClient provideOkhttpClient() {
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.readTimeout(15, TimeUnit.SECONDS);
client.connectTimeout(20, TimeUnit.SECONDS);
return client.build();
}
如果您想动态更改BASE_URL,有很多方法可以做到这一点。
public class ApiConstant {
public static String BASE_URL = "yourUrl";
private ApiConstant() {
}
}
创建一个@Scope for Retrofit,因为它可以更改
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface PerActivity {
}
然后在构建Retrofit时使用它
@Provides
@PerActivity
Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient) {
return new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl("first.url.com")
.client(ApiConstant.BASE_URL)
.build();
}
然后在初始化BASE_URL
时更改DaggerActivityComponent
。 (或者为新网址创建一个新的@Scope)
阅读this documentation了解更多详情
希望这有帮助!
答案 2 :(得分:1)
在您的AppModule中添加拦截器
@Provides
@Singleton
OkHttpClient provideOkHttpClient(Cache cache, MainInterceptor interceptor) {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.cache(cache)
.build();
return okHttpClient;
}
然后在您的活动或演示者中设置URL,然后再调用改造服务
mInterceptor.setInterceptor(urlname);
mRetrofitService.call();
答案 3 :(得分:0)
如果您已经设置了基本URL,但只想对一个API调用而不是对所有API覆盖它,则可以轻松完成。
@PUT("https://my-api.com/user")
fun cancelOrder(@Path("user") user: String): Single<MyResponse>
同样适用于POST和GET。