Ich versuche, eine Anfrage zu machen, die Daten vom Server zieht, bis es fertig ist, die Daten zu ziehen. Das Problem ist, dass die Antwort 21Data perPage hat. Aber es gibt ein Meta-Tag, um zu wissen, ob es eine nächste Seite gibt. Also, ich kann bis zum nextPage == totalPage
ziehen.Wiederholen Sie eine Nachrüstung Observable Request
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);
}
Und mein 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();
}
}
}
Meine Anfrage Logs
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)
Wenn Sie bemerken, http://theUrl.net/lga?page=1&per_page=21
wurde zweimal und http://theUrl.net/lga?page=3&per_page=21
genannt wurde 3 mal aufgerufen.
Also entschied ich mich, meine alte RestClient Class
Datei zu verwenden. Und es hat gut funktioniert. Aber es ist nichts falsch. Es lief die ganze Anfrage bis zum letzten. Ich kann immer noch nicht gefunden, was mit meiner ServiceGenerator class
RestClient Klasse falsch Datei
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();
}
}
}
Vielen Dank. Das hat es irgendwie gelöst. Aber ich bleibe immer noch bei meiner Anfrage, die zweimal protokolliert wird. Irgendetwas stimmt nicht mit meiner ServiceGenerator-Klasse? Ich habe meine Frage bearbeitet –
Zuerst versuchen Sie, Ihr Service-Objekt von 'ServiceGenerator.createService (ApiService.class, Token) zu cachen, oder verwenden Sie das Token als Parameter - die Dokumente sagen, es gibt eine @Header Annotation, die Sie verwenden können Ordnen Sie einen Parameter einem Header zu. Schließlich, wenn Sie nur die Ergebnisse behalten wollen, habe ich eine Bearbeitung hinzugefügt. –
Ich habe die Annotation @header nicht mehr verwendet, nachdem ich sie einmal in 'Retrofit 1.9' verwendet habe und es hat nicht geklappt. Ich benutze 'Retrofit 2.1' jetzt aber. Würde es nochmal versuchen –