Asynchrone Nachrüstanforderung ist ein Rückruf mit 2 Methoden onResponse() und onFailure().Generische Art der Nachrüstung für den benutzerdefinierten Anrufadapter
Ich möchte nicht immer diese 2 Methoden überschreiben und für den Fehlerfall behandeln.
Also, wenn ich die Google GithubBrowserSample von ApiResponse durch wollen, die die Nachrüstung Antwort Body-Wrapping und wandeln den Fehler wie folgt:
public class ApiResponse<T> {
public final int code;
@Nullable
public final T body;
@Nullable
public final String errorMessage;
public ApiResponse(Throwable error) {
code = -1;
body = null;
if (error instanceof IOException) {
errorMessage = "No network error";
}
else {
errorMessage = error.getMessage();
}
}
public ApiResponse(Response<T> response) {
code = response.code();
if (response.isSuccessful()) {
body = response.body();
errorMessage = null;
}
else {
String message = null;
if (response.errorBody() != null) {
try {
message = response.errorBody().string();
} catch (IOException e) {
e.printStackTrace();
}
}
if (message == null || message.trim().length() == 0) {
message = response.message();
}
errorMessage = message;
body = null;
}
}
public boolean isSuccessful() {
return code >= 200 && code < 300;
}
}
Ialso wollen die Gson Wandler verwenden, um die Nachrüstung Antwort zu konvertieren und dann wickeln es mit ApiResponse.
Wenn ich wie verwenden
Call<ApiResponse<Result>> requestCall = webClient.request1(xxx,xxx);
requestCall.enqueue(new Callback<ApiResponse<Result>> {});
Es Arbeit scheint nicht. Die JSON-Antwortdaten können nicht in das Result-Objekt geparst werden.
So denke ich über das Schreiben meiner eigenen benutzerdefinierten Call Adapter Referenz retrofit sample, um durch Retrofit Call zu ersetzen. Aber ich habe immer noch das Problem, generischen Typ zu konvertieren.
public class MyCallAdapterFactory extends CallAdapter.Factory {
@Nullable
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != MyCall.class) {
return null;
}
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType != ApiResponse.class) {
throw new IllegalArgumentException("type must be a resource");
}
if (! (observableType instanceof ParameterizedType)) {
throw new IllegalArgumentException("resource must be parameterized");
}
Type bodyType = getParameterUpperBound(0, (ParameterizedType) observableType);
Executor executor = retrofit.callbackExecutor();
return new MyCallAdapter<>(bodyType, executor);
}
}
public class MyCallAdapter<T> implements CallAdapter<T, MyCall<T>> {
private final Type responseType;
private final Executor callbackExecutor;
public MyCallAdapter(Type responseType, Executor callbackExecutor) {
this.responseType = responseType;
this.callbackExecutor = callbackExecutor;
}
@Override
public Type responseType() {
return null;
}
@Override
public MyCall<T> adapt(Call<T> call) {
return new MyCallImpl<>(call, callbackExecutor);
}
}
public class MyCallImpl<T> implements MyCall<T> {
private final Call<T> call;
private final Executor callbackExecutor;
MyCallImpl(Call<T> call, Executor callbackExecutor) {
this.call = call;
this.callbackExecutor = callbackExecutor;
}
@Override
public void enqueue(MyCallback<T> callback) {
call.enqueue(new Callback<T>() {
@Override
public void onResponse(Call<T> call, Response<T> response) {
/* This is the problem. it will seems wrap to ApiResponse<ApiResponse<Result>>> because T is <ApiResponse<Result>>.
*/
callback.onResult(new ApiResponse<>(response));
}
@Override
public void onFailure(Call<T> call, Throwable t) {
/** This one is also the issue. */
callback.onResult(new ApiResponse<>(t));
}
});
}
@Override
public void cancel() {
call.cancel();
}
@Override
public MyCall<T> clone() {
return new MyCallImpl<>(call.clone(), callbackExecutor);
}
}
public interface MyCallback<T> {
void onResult(ApiResponse<T> response);
}
Der obige Code hat das Problem bei der Verarbeitung von doppelt parametrisierten generischen Typen. Ich weiß nicht, wie ich damit umgehen soll.
Auch diesen Code auch hier wird abstürzen
Caused by: java.lang.NullPointerException: type == null
at retrofit2.Utils.checkNotNull(Utils.java:286)
at retrofit2.Retrofit.nextResponseBodyConverter(Retrofit.java:324)
at retrofit2.Retrofit.responseBodyConverter(Retrofit.java:313)
at retrofit2.ServiceMethod$Builder.createResponseConverter(ServiceMethod.java:736)
at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:169)
Könnte jemand helfen, wie MyCall<ApiResponse<Result>>
zu lassen MyCallback<ApiResponse<Result>>
nennen enqueue mit? Ergebnis ist das Parsen des JSON-Dateninhalts mit dem Gson-Konverter.
public class MyCallAdapter<T> implements CallAdapter<T, MyCall<ApiResponse<T>>> {
public MyCall<ApiResponse<T>> adapt(Call<T> call) {
/* This one will have the problem after changing MyCall<T> to MyCall<ApiResponse<T>>, Parameterized type mismatch.*/
return new MyCallImpl<>(call, callbackExecutor);
}
}
Kann mir jemand helfen, auf das Problem hinzuweisen?
'@Override public Typ responseType() { Rückgabewert null; } 'Antwort AntwortType in dieser Methode – Rahul
@Rahul, Vielen Dank für das Aufzeigen. Ich repariere es jetzt. –
Sie sind willkommen – Rahul