Type returnType = method.getGenericReturnType(); //处理不正确的返回形式 if (Utils.hasUnresolvableType(returnType)) { throw methodError( method, "Method return type must not include a type variable or wildcard: %s", returnType); } if (returnType == void.class) { throw methodError(method, "Service methods cannot return void."); } return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);//2
if (httpMethod == null) { throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.)."); }
if (!hasBody) { if (isMultipart) { throw methodError( method, "Multipart can only be specified on HTTP methods with request body (e.g., @POST)."); } if (isFormEncoded) { throw methodError( method, "FormUrlEncoded can only be specified on HTTP methods with " + "request body (e.g., @POST)."); } }
int parameterCount = parameterAnnotationsArray.length; parameterHandlers = new ParameterHandler<?>[parameterCount]; for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) { parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter); }
if (relativeUrl == null && !gotUrl) { throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod); } if (!isFormEncoded && !isMultipart && !hasBody && gotBody) { throw methodError(method, "Non-body HTTP method cannot contain @Body."); } if (isFormEncoded && !gotField) { throw methodError(method, "Form-encoded method must contain at least one @Field."); } if (isMultipart && !gotPart) { throw methodError(method, "Multipart method must contain at least one @Part."); } //将builder对象作为参数传给RequestFactory的构造函数 returnnew RequestFactory(this); }
Annotation[] annotations = method.getAnnotations(); Type adapterType; if (isKotlinSuspendFunction) { //...省略了关于kotlin的逻辑 } else { adapterType = method.getGenericReturnType(); }
CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);//2.1 Type responseType = callAdapter.responseType(); if (responseType == okhttp3.Response.class) { throw methodError( method, "'" + getRawType(responseType).getName() + "' is not a valid response body type. Did you mean ResponseBody?"); } if (responseType == Response.class) { throw methodError(method, "Response must include generic type (e.g., Response<String>)"); } // TODO support Unit for Kotlin? if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) { throw methodError(method, "HEAD method must use Void as response type."); } Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);//2.2
okhttp3.Call.Factory callFactory = retrofit.callFactory;//2.3 if (!isKotlinSuspendFunction) { returnnew CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);//2.4 } elseif (continuationWantsResponse) { //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object. return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>( requestFactory, callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter); } else { //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object. return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>( requestFactory, callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter, continuationBodyNullable); } }
public@Nullable CallAdapter<?, ?> get( Type returnType, Annotation[] annotations, Retrofit retrofit) { if (getRawType(returnType) != Call.class) { returnnull; } if (!(returnType instanceof ParameterizedType)) { thrownew IllegalArgumentException( "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>"); } final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class) ? null : callbackExecutor;
returnnew CallAdapter<Object, Call<?>>() { @Override public Type responseType(){ return responseType; }
@Override public Call<Object> adapt(Call<Object> call){ return executor == null ? call : new ExecutorCallbackCall<>(executor, call); } }; }
// Re-throw previous failures if this isn't the first attempt. if (creationFailure != null) { if (creationFailure instanceof IOException) { throw (IOException) creationFailure; } elseif (creationFailure instanceof RuntimeException) { throw (RuntimeException) creationFailure; } else { throw (Error) creationFailure; } }
// Create and remember either the success or the failure. try { return rawCall = createRawCall(); } catch (RuntimeException | Error | IOException e) { throwIfFatal(e); // Do not assign a fatal error to creationFailure. creationFailure = e; throw e; } }
// Remove the body's source (the only stateful object) so we can pass the response along. rawResponse = rawResponse .newBuilder() .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength())) .build();
int code = rawResponse.code(); if (code < 200 || code >= 300) { try { // Buffer the entire body to avoid future I/O. ResponseBody bufferedBody = Utils.buffer(rawBody); return Response.error(bufferedBody, rawResponse); } finally { rawBody.close(); } }
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody); try { T body = responseConverter.convert(catchingBody); return Response.success(body, rawResponse); } catch (RuntimeException e) { // If the underlying source threw an exception, propagate that rather than indicating it was // a runtime exception. catchingBody.throwIfCaught(); throw e; } }
T body = responseConverter.convert(catchingBody);
if (rawType == Completable.class) { // Completable is not parameterized (which is what the rest of this method deals with) so it // can only be created with a single configuration. returnnew RxJava2CallAdapter( Void.class, scheduler, isAsync, false, true, false, false, false, true); }
public Object adapt(Call<R> call){ Observable<Response<R>> responseObservable = isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call);
Observable<?> observable; if (isResult) { observable = new ResultObservable<>(responseObservable); } elseif (isBody) { observable = new BodyObservable<>(responseObservable); } else { observable = responseObservable; }
if (scheduler != null) { observable = observable.subscribeOn(scheduler); }
if (isFlowable) { // We only ever deliver a single value, and the RS spec states that you MUST request at least // one element which means we never need to honor backpressure. return observable.toFlowable(BackpressureStrategy.MISSING); } if (isSingle) { return observable.singleOrError(); } if (isMaybe) { return observable.singleElement(); } if (isCompletable) { return observable.ignoreElements(); } return RxJavaPlugins.onAssembly(observable); }