【发布时间】:2016-12-14 17:14:13
【问题描述】:
我真的想掌握使用Retrofit 和RxJava / RxAndroid 的窍门。我在以前的应用程序中使用普通的Retrofit2 Callback 方法完成了此操作,而没有使用Reactive Programming,并且效果很好。所以,这就是它。我需要Tail Recall 一个旨在从服务器获取所有Local Government 的函数。 API 使用分页 (I have to construct the URL with ?page=1, perPage=2)。我必须这样做,直到我拥有全部数据。所以,下面是我的Rx 代码
public static Observable<LgaListResponse> getPages(Context acontext) {
String token = PrefUtils.getToken(acontext);
BehaviorSubject<Integer> pageControl = BehaviorSubject.<Integer>create(1);
Observable<LgaListResponse> ret2 = pageControl.asObservable().concatMap(integer -> {
if (integer > 0) {
Log.e(TAG, "Integer: " + integer);
return ServiceGenerator.createService(ApiService.class, token)
.getLgas(String.valueOf(integer), String.valueOf(21))
.doOnNext(lgaListResponse -> {
if (lgaListResponse.getMeta().getPage() != lgaListResponse.getMeta().getPageCount()) {
pageControl.onNext(initialPage + 1);
} else {
pageControl.onNext(-1);
}
});
} else {
return Observable.<LgaListResponse>empty().doOnCompleted(pageControl::onCompleted);
}
});
return Observable.defer(() -> ret2);
}
还有我的 ServiceGenerator 类
public class ServiceGenerator {
private static final String TAG = "ServiceGen";
private static OkHttpClient.Builder builder = new OkHttpClient.Builder();
private static Retrofit.Builder retrofitBuilder =
new Retrofit.Builder()
.baseUrl(BuildConfig.HOST)
.addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(GsonConverterFactory.create(CustomGsonParser.returnCustomParser()));
public static <S> S createService(Class<S> serviceClass, String token) {
builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
/*builder.addNetworkInterceptor(new StethoInterceptor());*/
builder.connectTimeout(30000, TimeUnit.SECONDS);
builder.readTimeout(30000, TimeUnit.SECONDS);
if (token != null) {
Interceptor interceptor = chain -> {
Request newRequest = chain.request().newBuilder()
.addHeader("x-mobile", "true")
.addHeader("Authorization", "Bearer " + token).build();
return chain.proceed(newRequest);
};
builder.addInterceptor(interceptor);
}
OkHttpClient client = builder.build();
Retrofit retrofit = retrofitBuilder.client(client).build();
Log.e(TAG, retrofit.baseUrl().toString());
return retrofit.create(serviceClass);
}
public static Retrofit retrofit() {
OkHttpClient client = builder.build();
return retrofitBuilder.client(client).build();
}
public static class CustomGsonParser {
public static Gson returnCustomParser(){
return new GsonBuilder()
.setExclusionStrategies(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return f.getDeclaringClass().equals(RealmObject.class);
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
})
.create();
}
}
}
所以,我注意到在第一次调用时,我得到了响应,但在第二次调用中,440Error 被抛出。 URL 已形成,但请求会引发 400Error。如果我使用POSTMAN 进行测试,我不知道为什么它会抛出400 一切正常。而且,我也用我的旧代码进行了测试。 Log 太长了,所以我把它放在pastebin LOGS 任何帮助谢谢。我用RxAndroid / RxJava 编写了这个应用程序的大部分内容。谢谢
【问题讨论】:
-
首先,递归并不是使用 RxJava 和 Retrofit 进行分页的最佳方式。请参阅this question 的答案之一以获得更好的方法。其次,你在哪里订阅 observable?您似乎有多个订阅都触发了新请求,因为您生成的 Observable 是“冷的”。
-
我相信这条线
.subscribe(new Subscriber<LgaListResponse>() {是为了让我订阅onComplete、onError和onNext对吧?而这些(clientBus.hasObservers())clientBus是一个单例。因此,它不会多次生成。它只是向 UI 发送消息 -
是的,但是在某些时候你调用使用
getInstance' and then callgetLgas` 创建一个 LgaHandler 不是吗?现在你会多次调用它吗? -
不。 getInstance() 只被调用一次。那是单例。因此,内部函数 getLgas() 执行剩余的调用。这是我在旧应用程序中没有使用
RxJavagist.github.com/tonespy/c46d6d6729ab6618f906b050a2f22b1a@JohnWowUs -
您链接的日志显示两行
GET http://theUrl.com/lga?page=1&per_page=21 http/1.1和三行GET http://theUrl.com/lga?page=2&per_page=21 http/1.1。
标签: android rx-java retrofit2 rx-android