implementation 'com.squareup.retrofit2:retrofit:2.9.0'
val baseUrl = "https://api.github.com/"
val okHttpClient = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(90, TimeUnit.SECONDS)
.build()
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.build()
class RepoList {
@SerializedName("items") val items:List = emptyList()
}
data class Repo(
@SerializedName("id") val id: Int,
@SerializedName("name") val name: String,
@SerializedName("description") val description: String,
@SerializedName("stargazers_count") val starCount: String,
)
interface ApiService {
@GET("search/repositories?sort=stars&q=Android")
fun searRepos(@Query("page") page: Int, @Query("per_page") perPage: Int): Call
}
val apiService = retrofit.create(ApiService::class.java)
val call = apiService.searRepos(1, 5)
val response: Response = call.execute()
if (response.isSuccessful) {
val repo = response.body()
LjyLogUtil.d(repo.toString())
} else {
LjyLogUtil.d("code=${response.code()}, msg=${response.message()}")
LjyLogUtil.d(IOException("Unexpected code $response").message)
}
call.enqueue(object : Callback {
override fun onResponse(call: Call, result: Response) {
if (result.body() != null) {
val repoList: RepoList = result.body()!!
for (it in repoList.items) {
LjyLogUtil.d("${it.name}_${it.starCount}")
LjyLogUtil.d(it.description)
}
}
}
override fun onFailure(call: Call, t: Throwable) {
LjyLogUtil.d("onFailure:${t.message}")
}
})
@GET("api/items")
fun getRepos(): Call
@GET("https://api.github.com/api/items")
fun getRepos(): Call
/**
* method:网络请求的方法(区分大小写)
* path:网络请求地址路径
* hasBody:是否有请求体
*/
@HTTP(method = "GET", hasBody = false)
fun getRepos(@Url url: String): Call
@HTTP(method = "GET", path = "api/items/{userId}", hasBody = false)
fun getRepos2(@Path("userId") userId: String) : Call
@FormUrlEncoded
@POST("api/search")
fun searchRepo( @Field("name") repoName:String): Call
@Streaming
@GET
fun downloadFile(@Url url: String?): Call
@GET("api/items/{userId}/repos")
fun getItem(@Path("userId") userId: String): Call
//在发起请求时, {userId} 会被替换为方法的参数 userId(被@Path注解的参数)
@FormUrlEncoded
@POST("api/search")
fun searchRepo(@Url url: String, @Field("name") repoName: String): Call
@Streaming
@GET
fun downloadFile(@Header("RANGE") start:String , @Url url: String?): Call
@Headers("Content-Type: application/json;charset=UTF-8")
@POST("api/search")
fun searchRepo2(@Body params: Map): Call
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(object : Interceptor{
override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
val request=chain.request().newBuilder()
.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
.addHeader("Accept-Encoding", "gzip, deflate")
.addHeader("Connection", "keep-alive")
.addHeader("Accept", "*/*")
.addHeader("Cookie", "add cookies here")
.build()
return chain.proceed(request)
}
})
.build()
@GET("search/repositories?sort=stars&q=Android")
fun searRepos(@Query("page") page: Int, @Query("per_page") perPage: Int): Call
@GET("search/repositories?sort=stars&q=Android")
fun searRepos(@QueryMap params: Map): Call
@FormUrlEncoded
@POST("api/search")
fun searchRepo(@Url url: String, @Field("name") repoName: String): Call
@FormUrlEncoded
@POST("api/search")
fun searchRepo(@Url url: String, @FieldMap params: Map): Call
@POST("upload/imgFile")
@Multipart
fun uploadImgFile(
@Part("userId") userId: RequestBody?,
@PartMap partMap: Map,
@Part("file") file: MultipartBody.Part
): Call
@Multipart
@POST("upload/files")
fun uploadFiles(
@Part("userId") userId: RequestBody?,
@Part files: List
): Call
//使用:
val userId: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), "1111")
val paramsMap: MutableMap = HashMap()
paramsMap["userId"] = RequestBody.create(MediaType.parse("text/plain"), "123456")
paramsMap["userName"] = RequestBody.create(MediaType.parse("text/plain"), "jinYang")
paramsMap["taskName"] = RequestBody.create(MediaType.parse("text/plain"), "新建派单")
val imgFile=File(externalCacheDir, "ljy.jpg")
val requestFile: RequestBody =
RequestBody.create(MediaType.parse("multipart/form-data"),imgFile )
val partFile = MultipartBody.Part.createFormData("imageUrl", imgFile.name, requestFile)
apiService.uploadImgFile(userId,paramsMap,partFile)
val imgFile1=File(externalCacheDir, "ljy1.jpg")
val imgFile2=File(externalCacheDir, "ljy2.jpg")
val imgFile3=File(externalCacheDir, "ljy3.jpg")
val imageFiles= arrayOf(imgFile1,imgFile2,imgFile3)
val parts = ArrayList(imageFiles.size)
for (i in imageFiles.indices) {
val file: File = imageFiles[i]
parts[i] = MultipartBody.Part.createFormData(
"file_$i", file.name, RequestBody.create(
MediaType.parse("image/*"), file
)
)
}
apiService.uploadFiles(userId,parts)
@Headers("Content-Type: application/json;charset=UTF-8")
@POST("api/add")
fun addRepo(@Body repo: Repo): Call
@Headers("Content-Type: application/json;charset=UTF-8")
@POST("api/add")
fun addRepo2(@Body params: Map): Call
@Headers("Content-Type: application/json;charset=UTF-8")
@POST("api/add")
fun addRepo3(@Body body: RequestBody): Call
@FormUrlEncoded
@POST("api/add")
fun addRepo4(@Body body: FormBody): Call
//使用:
val repo = Repo(1, "name", "info", "20")
apiService.addRepo(repo)
val map: MutableMap = HashMap()
map["key"] = "value"
apiService.addRepo2(map)
val body: RequestBody = RequestBody
.create(MediaType.parse("application/json; charset=utf-8"), repo.toString())
apiService.addRepo3(body)
val formBody = FormBody.Builder()
.add("key", "value")
.build()
apiService.addRepo4(formBody)
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'//Gson的支持 [常用] [可选]
implementation 'com.squareup.retrofit2:converter-simplexml:2.9.0'//simplexml的支持 [可选]
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'//jackson的支持 [可选]
implementation 'com.squareup.retrofit2:converter-protobuf:2.9.0'//protobuf的支持 [可选]
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'//moshi的支持 [可选]
implementation 'com.squareup.retrofit2:converter-wire:2.9.0'//wire的支持 [可选]
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'//String的支持 [可选]
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(JacksonConverterFactory.create())
.addConverterFactory(SimpleXmlConverterFactory.create())
.addConverterFactory(ProtoConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.build()
//继承Converter.Factory
public final class GsonConverterFactory extends Converter.Factory {
//静态的create方法
public static GsonConverterFactory create() {
return create(new Gson());
}
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
private final Gson gson;
private GsonConverterFactory(Gson gson) {
this.gson = gson;
}
//重写responseBodyConverter方法,将响应体交给GsonResponseBodyConverter处理
@Override
public Converter responseBodyConverter(
Type type, Annotation[] annotations, Retrofit retrofit) {
TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonResponseBodyConverter<>(gson, adapter);
}
//重写requestBodyConverter方法,将请求体交给GsonRequestBodyConverter处理
@Override
public Converter, RequestBody> requestBodyConverter(
Type type,
Annotation[] parameterAnnotations,
Annotation[] methodAnnotations,
Retrofit retrofit) {
TypeAdapter> adapter = gson.getAdapter(TypeToken.get(type));
return new GsonRequestBodyConverter<>(gson, adapter);
}
}
//处理响应体的Converter,实现Converter接口
final class GsonResponseBodyConverter implements Converter {
private final Gson gson;
private final TypeAdapter adapter;
GsonResponseBodyConverter(Gson gson, TypeAdapter adapter) {
this.gson = gson;
this.adapter = adapter;
}
//重写convert方法,将ResponseBody通过Gson转为自定义的数据模型类
@Override
public T convert(ResponseBody value) throws IOException {
JsonReader jsonReader = gson.newJsonReader(value.charStream());
try {
T result = adapter.read(jsonReader);
if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
throw new JsonIOException("JSON document was not fully consumed.");
}
return result;
} finally {
value.close();
}
}
}
//处理请求体的Converter,实现Converter接口
final class GsonRequestBodyConverter implements Converter {
private static final MediaType MEDIA_TYPE = MediaType.get("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
private final Gson gson;
private final TypeAdapter adapter;
GsonRequestBodyConverter(Gson gson, TypeAdapter adapter) {
this.gson = gson;
this.adapter = adapter;
}
//重写convert方法,通过Gson将自定义的数据模型类转换为RequestBody
@Override
public RequestBody convert(T value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
JsonWriter jsonWriter = gson.newJsonWriter(writer);
adapter.write(jsonWriter, value);
jsonWriter.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}
//1. 自定义StringConverter,实现Converter
class StringConverter : Converter {
companion object {
val INSTANCE = StringConverter()
}
@Throws(IOException::class)
override fun convert(value: ResponseBody): String {
return value.string()
}
}
//2. 自定义StringConverterFactory,用来向Retrofit注册StringConverter
class StringConverterFactory : Converter.Factory() {
companion object {
private val INSTANCE = StringConverterFactory()
fun create(): StringConverterFactory {
return INSTANCE
}
}
// 只实现从ResponseBody 到 String 的转换,所以其它方法可不覆盖
override fun responseBodyConverter(
type: Type,
annotations: Array?,
retrofit: Retrofit?
): Converter? {
return if (type === String::class.java) {
StringConverter.INSTANCE
} else null
//其它类型不处理,返回null
}
}
3. 使用
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
// 自定义的Converter一定要放在官方提供的Converter前面
//addConverterFactory是有先后顺序的,多个Converter都支持同一种类型,只有第一个才被使用
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
class MapConverterFactory : Converter.Factory() {
companion object {
fun create(): MapConverterFactory {
return MapConverterFactory()
}
}
override fun responseBodyConverter(
type: Type,
annotations: Array,
retrofit: Retrofit
): Converter {
return MapConverter()
}
class MapConverter : Converter> {
@Throws(IOException::class)
override fun convert(body: ResponseBody): Map {
val map: MutableMap = HashMap()
val content = body.string()
val keyValues = content.split("&").toTypedArray()
for (i in keyValues.indices) {
val keyValue = keyValues[i]
val splitIndex = keyValue.indexOf("=")
val key = keyValue.substring(0, splitIndex)
val value = keyValue.substring(splitIndex + 1, keyValue.length)
map[key] = value
}
return map
}
}
}
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.9.0'//RxJava支持 [常用] [可选]
implementation 'com.squareup.retrofit2:adapter-java8:2.9.0'//java8支持 [可选]
implementation 'com.squareup.retrofit2:adapter-guava:2.9.0'//guava支持 [可选]
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addCallAdapterFactory(Java8CallAdapterFactory.create())
.addCallAdapterFactory(GuavaCallAdapterFactory.create())
.build()
//适配器工厂类,继承CallAdapter.Factory
public final class RxJava2CallAdapterFactory extends CallAdapter.Factory {
//静态的create方法
public static RxJava2CallAdapterFactory create() {
return new RxJava2CallAdapterFactory(null, false);
}
...
//Rxjava的调度器scheduler
private final @Nullable Scheduler scheduler;
private final boolean isAsync;
//构造方法
private RxJava2CallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
this.scheduler = scheduler;
this.isAsync = isAsync;
}
//重写get方法,返回RxJava2CallAdapter
@Override
public @Nullable CallAdapter, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class> rawType = getRawType(returnType);
...
return new RxJava2CallAdapter(
responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false);
}
}
//适配器类,实现CallAdapter接口
final class RxJava2CallAdapter implements CallAdapter {
private final Type responseType;
RxJava2CallAdapter(Type responseType,....){this.responseType = responseType;....}
...
//重写responseType方法
@Override
public Type responseType() {
return responseType;
}
//重写adapt方法,通过 RxJava2 将Call转换为Observable
@Override
public Object adapt(Call call) {
Observable> responseObservable =
isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call);
Observable> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return RxJavaPlugins.onAssembly(observable);
}
}
//1. 自定义Call
class LjyCall(private val call: Call) {
@Throws(IOException::class)
fun get(): T? {
return call.execute().body()
}
}
//2. 自定义CallAdapter
class LjyCallAdapter(private val responseType: Type) : CallAdapter {
override fun responseType(): Type {
return responseType
}
override fun adapt(call: Call): Any {
return LjyCall(call)
}
}
//3. 自定义CallAdapterFactory
class LjyCallAdapterFactory : CallAdapter.Factory() {
companion object {
private val INSTANCE = LjyCallAdapterFactory()
fun create(): LjyCallAdapterFactory {
return INSTANCE
}
}
override fun get(
returnType: Type,
annotations: Array,
retrofit: Retrofit
): CallAdapter? {
// 获取原始类型
val rawType = getRawType(returnType)
if (rawType == LjyCall::class.java && returnType is ParameterizedType) {
val callReturnType = getParameterUpperBound(0, returnType)
return LjyCallAdapter(callReturnType)
}
return null
}
}
//4. 使用
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
//也是放到前面,有先后顺序
.addCallAdapterFactory(LjyCallAdapterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
public static final class Builder {
//平台类型对象
private final Platform platform;
//网络请求工厂,默认使用OkHttpClient, 生产网络请求器(Call)
private @Nullable okhttp3.Call.Factory callFactory;
//url的基地址,注意这里的类型是HttpUrl,而非String
private @Nullable HttpUrl baseUrl;
//数据转换器工厂集合
private final List converterFactories = new ArrayList<>();
//适配器工厂集合
private final List callAdapterFactories = new ArrayList<>();
//回调方法执行器,在 Android 上默认是封装了 handler 的 MainThreadExecutor
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
this.platform = platform;
}
...
}
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
return "Dalvik".equals(System.getProperty("java.vm.name"))
? new Android() //
: new Platform(true);
}
...
}
static final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
...
static final class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}
public Retrofit build() {
//可以看到baseUrl是必须设置的
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//callFactory 默认使用OkHttpClient
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//这里就是对应上面Android的defaultCallbackExecutor,返回封装了Handler的MainThreadExecutor,
callbackExecutor = platform.defaultCallbackExecutor();
}
//数据解析器的集合:
// Make a defensive copy of the adapters and add the default Call adapter.
List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
//适配器的集合:
// Make a defensive copy of the converters.
List converterFactories =
new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
public Builder baseUrl(String baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
return baseUrl(HttpUrl.get(baseUrl));
}
public Builder baseUrl(HttpUrl baseUrl) {
Objects.requireNonNull(baseUrl, "baseUrl == null");
List pathSegments = baseUrl.pathSegments();
//如果host后面由路径,则必须以’/‘结尾
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
/**
* Returns a list of path segments like {@code ["a", "b", "c"]} for the URL {@code
* http://host/a/b/c}. This list is never empty though it may contain a single empty string.
*
*
* URL {@code pathSegments()}
* {@code http://host/} {@code [""]}
* {@code http://host/a/b/c"} {@code ["a", "b", "c"]}
* {@code http://host/a/b%20c/d"} {@code ["a", "b c", "d"]}
*
*/
public List pathSegments() {
return pathSegments;
}
public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
...
}
public final class Retrofit {
//网络请求配置对象的集合(对网络请求接口中方法注解进行解析后得到的对象)
private final Map> serviceMethodCache = new ConcurrentHashMap<>();
//下面几个在Builder中都有过介绍了
final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;
final List converterFactories;
final List callAdapterFactories;
final @Nullable Executor callbackExecutor;
final boolean validateEagerly;
Retrofit(
okhttp3.Call.Factory callFactory,
HttpUrl baseUrl,
List converterFactories,
List callAdapterFactories,
@Nullable Executor callbackExecutor,
boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
...
}
public T create(final Class service) {
validateServiceInterface(service);
return (T)
//通过动态代理创建接口的实例
Proxy.newProxyInstance(
//参数1:classLoader
service.getClassLoader(),
//参数2:接口类型数组
new Class>[] {service},
//参数3:实现了InvocationHandler的代理类
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadServiceMethod(method).invoke(args);
}
});
}
ServiceMethod> loadServiceMethod(Method method) {
ServiceMethod> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
//先在缓存map中获取
result = serviceMethodCache.get(method);
if (result == null) {
//取不到新建一个并加入缓存
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
abstract class ServiceMethod {
static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
...
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
+
abstract @Nullable T invoke(Object[] args);
}
final class RequestFactory {
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
...
static final class Builder {
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
//获取网络请求方法的注解:如@GET,@POST@HTTP
this.methodAnnotations = method.getAnnotations();
//获取网络请求方法参数的类型
this.parameterTypes = method.getGenericParameterTypes();
//获取网络请求参数的注解,如@Url,@Path,@Query等
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
//build方法
RequestFactory build() {
//解析网络请求方法的注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
...
//解析网络请求方法参数的类型和注解
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);
}
...
return new RequestFactory(this);
}
//解析网络请求方法的注解,看到下面的是不是很眼熟,有点豁然开朗了
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
} else if (annotation instanceof PATCH) {
parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
} else if (annotation instanceof POST) {
parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
} else if (annotation instanceof PUT) {
parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
} else if (annotation instanceof OPTIONS) {
parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
} else if (annotation instanceof HTTP) {
HTTP http = (HTTP) annotation;
parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
} else if (annotation instanceof Multipart) {
if (isFormEncoded) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isMultipart = true;
} else if (annotation instanceof FormUrlEncoded) {
if (isMultipart) {
throw methodError(method, "Only one encoding annotation is allowed.");
}
isFormEncoded = true;
}
}
//解析网络请求方法参数的类型和注解
private @Nullable ParameterHandler> parseParameter(
int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
ParameterHandler> result = null;
if (annotations != null) {
for (Annotation annotation : annotations) {
ParameterHandler> annotationAction =
parseParameterAnnotation(p, parameterType, annotations, annotation);
...
result = annotationAction;
}
}
...
return result;
}
//解析网络请求方法参数的类型和注解
@Nullable
private ParameterHandler> parseParameterAnnotation(
int p, Type type, Annotation[] annotations, Annotation annotation) {
//判断参数的注解注解
if (annotation instanceof Url) {
...
gotUrl = true;
//判断参数的类型
if (type == HttpUrl.class
|| type == String.class
|| type == URI.class
|| (type instanceof Class && "android.net.Uri".equals(((Class>) type).getName()))) {
return new ParameterHandler.RelativeUrl(method, p);
}
...
} else if (annotation instanceof Path) {
...
gotPath = true;
Path path = (Path) annotation;
String name = path.value();
validatePathName(p, name);
Converter, String> converter = retrofit.stringConverter(type, annotations);
return new ParameterHandler.Path<>(method, p, name, converter, path.encoded());
} else if (annotation instanceof Query) {
...
} else if (annotation instanceof QueryName) {
...
} else if (annotation instanceof QueryMap) {
...
} else if (annotation instanceof Header) {
...
} else if (annotation instanceof HeaderMap) {
...
} else if (annotation instanceof Field) {
...
} else if (annotation instanceof FieldMap) {
...
} else if (annotation instanceof Part) {
...
} else if (annotation instanceof PartMap) {
...
}
return null; // Not a Retrofit annotation.
}
}
...
}
static HttpServiceMethod parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
...
//获取方法注解
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
...
} else {
//网络请求方法的返回值类型就是请求适配器的类型
adapterType = method.getGenericReturnType();
}
//请求适配器
CallAdapter callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
Type responseType = callAdapter.responseType();
...
//数据解析器
Converter responseConverter =
createResponseConverter(retrofit, method, responseType);
//从retrofit获取请求工厂,默认的话是OkHttpClient
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
...
}
//CallAdapted继承了HttpServiceMethod
static final class CallAdapted extends HttpServiceMethod {
private final CallAdapter callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter responseConverter,
CallAdapter callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
//adapt方法的实现,调用callAdapter的adapt方法
@Override
protected ReturnT adapt(Call call, Object[] args) {
return callAdapter.adapt(call);
}
}
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
val apiService = retrofit.create(ApiService::class.java)
val call = apiService.searRepos(1, 5)
val response: Response = call.execute()
if (response.isSuccessful) {
val repo = response.body()
LjyLogUtil.d(repo.toString())
} else {
LjyLogUtil.d(IOException("Unexpected code $response").message)
}
@Override
public Response execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
//创建okhttp3.Call
call = getRawCall();
}
if (canceled) {
call.cancel();
}
return parseResponse(call.execute());
}
@GuardedBy("this")
private okhttp3.Call getRawCall() throws IOException {
okhttp3.Call call = rawCall;
if (call != null) return call;
...
return rawCall = createRawCall();
...
}
private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
if (call == null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
@Override
public void enqueue(final Callback callback) {
Objects.requireNonNull(callback, "callback == null");
okhttp3.Call call;
Throwable failure;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall = createRawCall();
} catch (Throwable t) {
throwIfFatal(t);
failure = creationFailure = t;
}
}
}
if (failure != null) {
callback.onFailure(this, failure);
return;
}
if (canceled) {
call.cancel();
}
call.enqueue(
new okhttp3.Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
Response response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
throwIfFatal(e);
callFailure(e);
return;
}
try {
callback.onResponse(OkHttpCall.this, response);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callFailure(Throwable e) {
try {
callback.onFailure(OkHttpCall.this, e);
} catch (Throwable t) {
throwIfFatal(t);
t.printStackTrace(); // TODO this is not great
}
}
});
}
Response parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// 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();
}
}
if (code == 204 || code == 205) {
rawBody.close();
return Response.success(null, rawResponse);
}
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;
}
}
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.client(okHttpClient)
// 自定义的Converter一定要放在官方提供的Converter前面
.addConverterFactory(StringConverterFactory.create())
.addConverterFactory(MapConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(LjyCallAdapterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
— 策略类之间可以自由切换,由于策略类都实现同一个接口,所以使它们之间可以自由切换。
val retrofit = Retrofit.Builder()
.baseUrl(baseUrl)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addCallAdapterFactory(Java8CallAdapterFactory.create())
.addCallAdapterFactory(GuavaCallAdapterFactory.create())
.build()
//call为被观察者,Callback为观察者
call.enqueue(object : Callback {
override fun onResponse(call: Call, result: Response) {
if (result.body() != null) {
val repoResult: RepoList = result.body()!!
for (it in repoResult.items) {
LjyLogUtil.d("${it.name}_${it.starCount}")
}
}
}
override fun onFailure(call: Call, t: Throwable) {
LjyLogUtil.d("onFailure:${t.message}")
}
})
final class DefaultCallAdapterFactory extends CallAdapter.Factory {
private final @Nullable Executor callbackExecutor;
DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public @Nullable CallAdapter, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
...
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
return new CallAdapter
//ExecutorCallbackCall是装饰者,而里面真正去执行网络请求的还是OkHttpCall
static final class ExecutorCallbackCall implements Call {
final Executor callbackExecutor;
final Call delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override
public void enqueue(final Callback callback) {
Objects.requireNonNull(callback, "callback == null");
delegate.enqueue(
new Callback() {
@Override
public void onResponse(Call call, final Response response) {
callbackExecutor.execute(
() -> {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on
// cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
});
}
@Override
public void onFailure(Call call, final Throwable t) {
callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
}
});
}
}
public final class Retrofit {
private final Map> serviceMethodCache = new ConcurrentHashMap<>();
final okhttp3.Call.Factory callFactory;
final HttpUrl baseUrl;
final List converterFactories;
final List callAdapterFactories;
final @Nullable Executor callbackExecutor;
final boolean validateEagerly;
...
}
//Retrofit.create
public T create(final Class service) {
validateServiceInterface(service);
return (T)
//通过动态代理创建接口的实例
Proxy.newProxyInstance(
//参数1:classLoader
service.getClassLoader(),
//参数2:接口类型数组
new Class>[] {service},
//参数3:实现了InvocationHandler的代理类
new InvocationHandler() {
...
});
}
abstract class AbsObject {
abstract fun doSomething()
}
class RealObject : AbsObject() {
override fun doSomething() {
LjyLogUtil.d("RealObject.doSomething")
}
}
class ProxyObject(private val realObject: RealObject) : AbsObject() {
override fun doSomething() {
LjyLogUtil.d("before RealObject")
realObject.doSomething()
LjyLogUtil.d("after RealObject")
}
}
//使用
val realObject = RealObject()
val proxyObject = ProxyObject(realObject)
proxyObject.doSomething()
interface Subject {
fun doSomething()
}
class Test : Subject {
override fun doSomething() {
LjyLogUtil.d("Test.doSomething")
}
}
class DynamicProxy(private val target: Subject) : InvocationHandler {
override fun invoke(proxy: Any?, method: Method?, args: Array?): Any? {
LjyLogUtil.d("Proxy:${proxy?.javaClass?.name}")
LjyLogUtil.d("before target")
//Kotlin中数组转为可变长参数,通过前面加*符号
val invoke = method!!.invoke(target, *(args ?: emptyArray()))
LjyLogUtil.d("after target")
return invoke
}
}
//使用:
val test = Test()
val myProxy = DynamicProxy(test)
val subject: Subject =
Proxy.newProxyInstance(
test.javaClass.classLoader,
test.javaClass.interfaces,
myProxy
) as Subject
subject.doSomething()
LjyLogUtil.d("subject.className:" + subject.javaClass.name)