私は、データを取得し終えるまで、サーバーからデータを取得するリクエストを作成しようとしています。問題はこれです、レスポンスには21Data perPageがあります。しかし、次のページがあるかどうかを知るメタタグがあります。だから、私はnextPage == totalPage
まで引っ張ることができます。リピート可観察可能なリクエスト
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();
}
}
}
私の要求ログ
E/ServiceGen: http://theUrl.net/
D/OkHttp: --> GET http://theUrl.net/lga?page=1&per_page=21 http/1.1
D/OkHttp: x-mobile: true
D/OkHttp: --> END GET
D/OkHttp: --> GET http://theUrl.net/lga?page=1&per_page=21 http/1.1
D/OkHttp: x-mobile: true
D/OkHttp: --> END GET
D/OkHttp: <-- 200 OK http://theUrl.net/lga?page=1&per_page=21 (929ms)
D/OkHttp: Date: Wed, 10 Aug 2016 09:01:00 GMT
D/OkHttp: Content-Type: application/json; charset=utf-8
D/OkHttp: <-- 200 OK http://theUrl.net/lga?page=1&per_page=21 (933ms)
D/OkHttp: Date: Wed, 10 Aug 2016 09:01:00 GMT
D/OkHttp: Content-Type: application/json; charset=utf-8
D/OkHttp: --> GET http://theUrl.net/lga?page=2&per_page=21 http/1.1
D/OkHttp: --> END GET
D/OkHttp: --> GET http://theUrl.net/lga?page=2&per_page=21 http/1.1
D/OkHttp: --> END GET
D/OkHttp: --> GET http://theUrl.net/lga?page=2&per_page=21 http/1.1
D/OkHttp: --> END GET
D/OkHttp: <-- 400 Bad Request http://theUrl.net/lga?page=2&per_page=21 (695ms)
D/OkHttp: <-- END HTTP (177-byte body)
D/OkHttp: <-- 400 Bad Request http://theUrl.net/lga?page=2&per_page=21 (696ms)
D/OkHttp: <-- END HTTP (177-byte body)
D/OkHttp: <-- 400 Bad Request http://theUrl.net/lga?page=2&per_page=21 (696ms)
あなたはhttp://theUrl.net/lga?page=1&per_page=21
が二回呼ばれていたとhttp://theUrl.net/lga?page=3&per_page=21
が3回呼び出された気付いた場合。
私は古いRestClient Class
ファイルを使用することに決めました。それはうまくいった。しかし、間違ったことはありません。それは最後まで要求全体を実行しました。私はまだ私のServiceGenerator class
RestClientクラス
public class RestClient {
private static final String TAG = "RestClient";
private static ApiService apiEndpointInterface;
private static Context context;
/*static {
setupRestClient();
}*/
public static ApiService get(Context cont) {
context = cont;
if (apiEndpointInterface != null)
return apiEndpointInterface;
setupRestClient();
return apiEndpointInterface;
}
private static void setupRestClient() {
// Define the interceptor, add authentication headers
Interceptor interceptor = chain -> {
Request newRequest = chain.request().newBuilder()
/*.addHeader("x-mobile", "true")*/
.addHeader("Authorization", "Bearer " + PrefUtils.getToken(context)).build();
return chain.proceed(newRequest);
};
// Add the interceptor to OkHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.interceptors().add(interceptor);
builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
builder.addNetworkInterceptor(new StethoInterceptor());
builder.connectTimeout(30000, TimeUnit.SECONDS);
builder.readTimeout(30000, TimeUnit.SECONDS);
OkHttpClient client = builder.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BuildConfig.HOST)
.addCallAdapterFactory(RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io()))
.addConverterFactory(GsonConverterFactory.create(CustomGsonParser.returnCustomParser()))
.client(client)
.build();
apiEndpointInterface = retrofit.create(ApiService.class);
}
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();
}
}
}
ありがとうございました。それはそれを解決しました。しかし、私は依然として私のリクエストが2回記録されていることに悩まされています。 ServiceGeneratorクラスに問題がありますか?私は自分の質問を編集しました –
最初に、 'ServiceGenerator.createService(ApiService.class、token)'からサービスオブジェクトをキャッシュしてみるか、そのトークンをパラメータとして使用してください - ドキュメントには@Header Annnotationがありますパラメータをヘッダにマップする。最後に、結果を保持したい場合は、編集を追加しました。 –
'Retrofit 1.9'で@ headerアノテーションを一度使用した後、@headerアノテーションの使用を中止しましたが、うまくいきませんでした。私は 'Retrofit 2.1'を使用しています。もう一度試してみる –