「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你应战!」

Retrofit 全面解析

A type-safe HTTP client for Android and Jaokhttp长处va

源码剖析版别:
implementation 'com.squareup.retrofit2:retrofit:kotlin实战2.9.0'

Retrofit的运用

关于Re线程是什么意思trofit的运用,这儿就不再多于的讲解了,信任只需是做Android开发的都会运用Retrofit
square.github.io/retrofit/
最简略的运用办法如下:

interface GitHubService {
@GET("users/{user}/repos")
fun listRepos(@Path("user") usekotlin为什么盛行不起来r:String?):Call<List<Rep线程和进程的差异是什么o>>
}
val retrofit = Retrofit.Builder()
.ba缓存视频变成本地视频seUrl("https://api.okhttp运用github.com/")
.addCookhttp原理 面试nverterFactory(okhttp运用过程GsonConverterFactory.create()) //gsokhttp3on的转化工厂
.kotlin官网build()
retrofit.create(Gi线程的生命周期是什么tHubService::class.java).listRepos("octocat缓存视频在手机哪里找")
.enqueue(object :Callback<List<Repo>>{
override fun onResp缓存是什么意思onse(call: Call<List<Repo>>, response: Response<List<Repo>>线程安全) {
println(response.body()?.size)
}
override f缓存视频兼并app下载un onFailure(call: Call<List<Repo>>, t: Throwable) {
TODO("Not yet implemented")
}
})

看源码的思路,专心于一条线路,直到看懂这条线路。

下面咱们先专心于create办法这条道路A线程撕裂者,然后是enqueue这条道路B.
Retrofit 全面解析

从Create办法剖析

接口测验面这段代码,经过Builder办法构建Retrofit实例

val retrofit = Retrofit.Builder()
.baseUrl(线程池"https://api.github.com/")
.addConverterFactory(GsonConverterFa接口ctory.create()) //gson的转化工厂
.build()

retrofit.create() 办法进行初始化代码如下缓存视频兼并
经过Java的动态署理办法,对传递接口测验过来的Class署理办法,留神Class有必要是接口,Java中的动态署理只能署理接口。
咱们首要看第一步validateServiceInterface办法干了什么?

  public <T> T create(final Class<接口测验面试题T> service) {
//1. 进行初始化验证service接口 先看一下这个办法
validateServiceInterface(sokhttp结构ervice);
//2. 回来署理政策  
return (T)
//运用java供给的动态署理
Proxy.newProxyInstkotlin教程ance(
service.getClassLoader(),
new Class&线程池创立的四种lt;?>[] {缓存视频兼并service},
new InvocationHandler() {
private final Platform platform =OKHttp Pl缓存视频怎样转入相册atform.get();
private final Object[] emptyArgs = new Object[0];
@Overr缓存文件在哪里ide
public @Nullable O线程和进程的差异是什么bjekotlin怎样读ct in缓存视频怎样转入本地视频voke(Object proxy, Method method, @Nullable Object[] arg缓存视频怎样转入本地视频s)
throws Throwable {
// If the method is a method from Obje接口crc过错计数ct then defer to normal invocation.
if (method.getDe接口测验面试题claringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? arokhttp3gs : emptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
: loadService线程Method(meth缓存视频在手机哪里找od).invoke(ar缓存文件在哪里gs);
}
});
}

validateServiceInterface 首要作用初始化的时分进行验证,验证service class是否运用正确:

  private vo接口id validateServiceInterface(Class&l接口测验面试题t;?> service) {
//这个clasokhttp和retrofits有必要是一个接口,假定不是接口就会报错
if (!servikotlin中心编程ce.isInterkotlin怎样读face()) {
throw new IllegalArgumentException("API declarations mkotlin中心编程ust be interfac接口crc过错计数es.");
}
//将接口参与到队伍中  
Deque<Class<?>> check = neokhttp结构w Array线程池的七个参数Deque<>(1);
check.add(serkotlin为什么盛行不起来vice);
while (!check缓存文件在哪里.isEmpty()) {
//从队伍接口是什么中取出接口类  
Class<?kotlin教程> candidate = check.removeFokhttpclientirst();
//class 接口类 不能有泛型 如:GithubService<T> 会报错
if (candida缓存视频兼并app下载te.getTypeParameters().length != 0) {
StringBuilder message =
new StringBuilder("Type parameters are unsupporkotlin中心编程ted on缓存视频兼并app下载 ").append(candidate.getName());
if (candidate !=线程是什么意思 service) {
message.append(" which is aokhttp3源码剖析n interface of ").append(service.getName());
}
throw new IllegalArgumentException(message.toString());
}
//判别接口 是否还有继承 假定有持续循环  
Collections.addAll(check, candidate.getInterfacesokhttp和retrofit());
}
// 开关,validateEagerly 开发和正式 能够快速验证
if (validateEagerly) {
Platfor线程池m platform = Platform.get();
for (Method method : servicokhttp是干什么用的e.getDeclaredMethods()) {
//过滤接口的默许办法和静态办法
if (!platform.isDefaultMethod(接口crc过错计数method) && !Modifier.isStatic(mkotlin面试题ethod.getModifiers())) {
//验证和加载接口类的办法  
loadServiceMethod(method);
}
}
}
}

其实validateEagerly 首要用来在初始化的时分进行验证接口中的一切办法配备,一般在开发阶段进行设置为true,Retrofit给出的说明如下:

 /**okhttpclient
* When calling {@link #create} on缓存 the result缓存是什么意思ing {@link Retrofit缓存视频} instance, eagerly validate the
* configuration of all methods in the supplied interface.
当在作用{@link Retrofit}实例上调用{@link #create}时,急切地验证供给的接口中一切办法的配备。
*/
public Builder validateEagerly(boolean validateEagerly) {
this.validateEagerly = validateEagerly;
return this;
}

在初始化验证经过之后,会经过Jakotlin教程va中的动态署理办法,生成署理政策。

动态署理

Java中的动态署理,经过Proxy生成接口的署理政策,当调用署理政策的办法的时分就会调用invoke办法。这也是Retrofit的中心的进口。

    return (T缓存文件在哪里)
//运用java供给的动态署理
Proxy.newProxyInstance(
servi线程和进程的差异是什么ce.getClassLoader(接口自动化),
new C接口的定义lass<?>[] {service},
new InvocationHandler() {
private final Platforkotlin实战m platform = Platform.get();
private fina线程池的七个参数l Ob接口是什么ject[] emptyArgs = new Objectokhttp3源码剖析[0];
@Override
public @Nullable ObjecKotlint invoke(Object proxy, Method method, @Nullable Ob接口测验面试题ject[] args)线程是什么意思
thro缓存ws Throwable {
// If the met线程的概念hod is a method from Object then defer to n线程的生命周期是什么ormal invocation.
// Object类的办法      
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : eokhttp原理 面试mptyArgs;
return platform.isDefaultM接口crc过错计数ethod(method) //考虑java接口crc过错计数8的兼容问题
? platform.invokeDefa线程ultMethod(method, service,kotlin面试题 proxy, ar缓存视频怎样转入相册gs) //假定是默许办法 直接调用默许办法
: loadServiceMethod(method).invoke(args);
}
});

其实动线程池的七个参数态署理的原理非常简略,实际上等价于下面的代码:首要去重视invok接口的定义e回调办法中

class Pkotlin教程roxyGitHubService : GitHubService {
val invocationHandler:InvocationHandler = InvocationHandler(object : (Any, Method, Array<Any>) -> Any{
override fun invoke(p1: Any, p2: Method, p3: Array<Any&g线程撕裂者t;): Any {
// If the m缓存是什么意思ethod is a method from Object then defer to normal invocakotlin面试题tion.
if (method.getDeclaringClass() == Object.class)Kotlin {
return me线程是什么意思thod.invoke(this, args);
}
args = args != null ? args : em线程安全ptyArgs;
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method缓存视频兼并, service, proxy, args)
: load接口自动化ServiceMethookhttp运用过程d(method).invoke(args);
}
})
override fun listRepos(user: String?): Call<List<Repo>> {
val method = Git接口卡HubService::class.java.getDeclaredMethod("listRepos",String::class线程安全.java)
invocationHan线程的概念dler.invoke(this,method,user)
}
}

究竟中线程池的七个参数心的办法便是lkotlin教程oadServiceMethod办法,究竟调用了invoke()办法。下面来看loadSerKotlinviceMethod做了什么?

loadServi接口的定义ceMethod

loadSerkotlin为什么盛行不起来viceMethod代码如下:从Map集结获取Serv接口测验iceMethod 并回来,Retrifit做了缓存处理,下一次在调用直接从缓存中获取。这么这个ServiceMethod类有什么作用呢?

  ServiceMethod<?> loadServiceokhttp是干什么用的Method(Method method) {
//获取缓存的取出来,缓存视频在手机哪里找serviceMethodCache便是一个Map集结  
ServiceMethod<?> result = serviceMethodCache.get(method);
//假定存在的话则直接回来  
if (result != null) return result;
synchronized (serviceMethodCache) {
result =线程的生命周期是什么 serviceMethodCache.get(method);
//假定没有则存入缓存  
ifokhttp结构 (result == null) {
//处理接口办法  
result = ServiceMethod.parseAnnotations(this, method);
serviceMetho接口crc过错计数dCache.put(m接口是什么ethod, result);
}
}
return缓存视频兼并 result;
}

下面okhttp3咱们来看Servic缓存视频变成本地视频eMethod类,是一个抽象类,invoke办法并没有结束,能够看到经过parseAnnotations办法回来了ServiceMethod类的实例政策,咱们找到ServiceMethod的结束类HttpServ线程的几种状况iceMethod类。
这儿咱们先把重视点放到invoke办法上,

abstract class ServiceMethod<T> {
staokhttp3tic <T> Se接口测验面试题rviceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
// 解析办法的注解,回来值类型,传递的参数  
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
//获取办法的回来值类缓存视频在手机哪里找
Type retukotlin下载rnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
metho缓存视频在手机哪里找d,
"Method return type must not include a type variable or wildcard: %s",
returnType);
}
if (returnType == void.class) {
throw methodErrkotlin面试题or(method, "Service methokhttp长处ods cannot return void.");
}
return HttpServiceMethod.parseAnnotations(reokhttpclienttrofit接口, method, requestFactory);
}
abstract @Nuokhttp是干什么用的llable T invoke(Object[] args);
}

HttpServiceMethod

咱们先看invoke办法的结束:

  @Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<&kotlin下载gt;(requestFactory, args, callFactor接口类型y,kotlin为什么盛行不起来 responseConverter接口crc过错计数);
return adapt(call, args);
}

从invoke办法中能够看到有两条线路:OkHttpCall以及adapt. 经过源kotlin怎样读码线路剖析图如下,这两条线路咱们先看OkHttpCall这条线路C。
Retrofit 全面解析

线路C -> OkHtkotlin言语tpCall

能够看到OkHttpCall结束了Ca接口测验面试题ll接口,Call接口是否很熟悉,在咱们运用Retrofit的运用,接口的办法会回来一个call

interface GitHubService {
@GET("user接口卡s/{user}/repos")
fun listRepos(@Path("user") us线程的概念er:String线程池的七个参数?):Call&l缓存视频怎样转入相册t;List<Repo>>
}

那也便是说,OkHttpCall结束了enqueue()办法。代码如下:

@Overr接口和抽象类的差异ide
public void enqueue(final Callback<T&接口gt; callback) {
.........
//okhttp的call实例
okhttp3.线程的概念Call call;
Throwable failure;
synchronized (this) {
..........
executed = true;
call = rawCall;
failure = creationFailure;
if (call == null && failure == null) {
try {
call = rawCall =kotlin下载 createRawCallkotlin言语();
} catch (Throwable t) {
throkotlin为什么盛行不起来wIfFatal(t);
failure = creationFailure = t;
}
}
}
.......
// 究竟调用了okhtt线程的生命周期是什么p的enqueue办法
call.enqueOKHttpue(
new okotlin下载khttp3.kotlin为什么盛行不起来Callback() {
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response rawRespoOKHttpnse) {
Response<T> response;
trokhttp3y {
//解析回来作用  
re接口和抽象类的差异sponse = parseResponse(rawResponse);
} catch (T线程安全hrowable e) {
throwIfFatal(e);
callkotlin怎样读Failure(e);
return;
}
.....
}
@Override
public void onFailure(okhttp3.Call call, IOException e) {
callFailure(e);
}
private void callkotlin下载Failure(Th缓存rowable e) {
.......
}
});
}

经过enqueue咱们又发现了两条新的线路:createRawCall()办法(创立okhttp的call政策接口测验)以及parseResponse()办法(解析回来值)。
Retrofit 全面解析

createRawCall

首要剖析线路接口E怎样创立okhttp.call的政策实例的。如下代码首要经过callFacokhttp运用tory和requestFactory进行创立的,在创立OkHttpCall实例的时分传递进来的。

  private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(requestFactory.cr缓存是什么意思eate(arkotlin极简教程gs)线程是什么意思);
if (call ==接口自动化 null) {
throw new NullPointerException("Call.Factory returned null.");
}
return call;
}
OkH接口文档ttpCall(
Re接口类型questFactory requestFactory,
Object[接口自动化] args,
okhtt缓存视频变成本地视频p3.Call.Factory callFactory,
Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args = args;
this.callFactory = callFactoryokhttp3;
this.responseConverterokhttp是干什么用的 = responseCon接口卡verter;
}

咱们沿着链路向上寻找.此刻线路图如下:
Retrofit 全面解析
查找流程:Ht接口的定义tpServiceMethod.invoke –kotlin教程> HttpServiceMethod.parseAnnotations()
如下代码:callFactory和requestFact线程是什么意思ory是由外部传递进来的,持续向上查找

  static <ResponseT接口卡, ReturnT> Hokhttp运用ttpSer接口卡viceMethod<ResponseT,okhttp运用 ReturnT> parseAnnotations(接口卡
Retrofit retrofit, Method method, RequestFactory requestFactory) {
......
okhtt接口文档p3.Call.Factory callFactory = retrofit.callFactoryokhttp3源码剖析;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestF线程安全actory, callFactory,线程的生命周期是什么 respons缓存是什么意思eConverter, callAdapter);
}okhttp运用
.....
}

代码如下:咱们看到了RequestFactory,总算找到他了,进去看看干了些啥。

abstract class ServiceMethkotlin教程od<T> {
static <T> ServiceMethod<T> parseAnokhttp长处notationkotlin教程s(Retrofit retrofit, Methokotlin实战d method) {
RequestFactory requestFa缓存视频在手机哪里找ctorokhttp运用过程y = RequestFactory.parseAnnotations(retrofit, method);
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(okhttp运用returnType)) {
throw methodError(接口测验
method,
"Method return type must not include缓存视频在手机哪里找 a type variable ookhttpclientr wildcard: %s",
returnType);
}
if (returnTyp线程和进程的差异是什么e == void.class) {
throw methodE线程是什么意思rror(metho缓存d, "Service methods cannot return void.");
}
reokhttp结构turn HttpServiceMethod接口测验.parseAnnotationokhttp结构s(retrofit, method, requestFactory);
}
}

RequestFactory: 能够看到首要是处理接口类service.class的办法的注解的

    RequestFactory build() {
for (Annotation annotation : methodAnnota接口和抽象类的差异tions) {
pa缓存文件在哪里rsekotlin言语MethodAnnotation(annotation);
}
....
}

处理结束之后会得到以下的值
Retrofit 全面解析
咱们回调线路E
Retrofit 全面解析
在createRawCall()办法中调用了requestFactory.create()办法。

  private okhttp3.Call createRawCall() throws IOException {
okhttp3.Call call = callFactory.newCall(reokhttp是干什么用的questFactory.create(args));
if (缓存视频兼并app下载call == null) {
thrKotlinow ne线程撕裂者w NullPointerExcepti缓存on("Call.Factory returned null.");
}
return call;
}

requestFactory.create() 代码如下:究竟便是得到了okhttp3.request这个RequestFactory其实便是拼接恳求的

  okht缓存视频兼并tp3.Request create(Object[] args) throws IOExc接口卡eption {
@SuppressWarnings("unchecked") // It is an error to invoke a method with the wron接口测验g arg types.
ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;
int argumentCount = args.lkotlin实战eng接口和抽象类的差异th;
.接口和抽象类的差异......
Reque缓存是什么意思stBuilder reques接口类型tBuilder =
new RequestBuilder(
httpMethod,
baseUrl,
re接口类型lativeUrl,
headers,
contentType,
haskotlin下载Body,
isF接口类型orm线程和进程的差异是什么Encoded,
isMultipart);
if (isKotlinSuspendFu接口的定义nction) {
// The Continuation is缓存的视频怎样保存到本地 the last parameter and t缓存视频兼并he handlers array contains null at that index.
argumentCount--;
}
List&lt缓存视频怎样转入相册;Object> argumentList = new ArraKotlinyList<>(argumentCount);
for (int p = 0; p < argumentCount; p+kotlin言语+) {okhttpclient
argumentList.add(args[p]);
handlers[p].apply(requestBuilder,okhttp是干什么用的 args[p]);
}
return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}

那么线路E就理清楚了,其实便是okhttpc线程池的七个参数lient.newCall(接口测验request)。这不便是okhttp的运用的api吗。
Retrofit 全面解析
OK,requestFactory咱们现已接口的定义清楚了,其实便是对service class接口的办法中的注解处理,缓存文件在哪里判别是get和缓存post等等,然后回来okhttp3.request.

下面咱们看callFactory: 从代码中能够看出是从retrofit.callFactory获取的,从build办法能够看到其实便是okHttpClient,咱们也能够自己进行设置okHttpClient

retrofit.callFactory
public Retrofit build() {
if (baseUrl == null) {
throw new Illega线程的概念lStateException("Base URL required.")接口和抽象类的差异;
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new Ok接口和抽象类的差异HttpClient();
}
....
}接口卡

Retrofit 全面解析

咱们再看一下拾掇的线路:这样看会非常清楚的流程
Retrofit 全面解析

parseResponse

下面咱们在看parseResponse线路F是怎样实施的。代码如下(在OkHttpCall类中):究竟经过responsekotlin面试题Converterconvekotlin怎样读rt办法处理的

  Response<T> paokhttp3源码剖析rseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
//.......
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rokhttp运用过程awBody);缓存视频变成本地视频
try {
T body = responseConverter.convert(catchingBody);
re缓存视频tuokhttp是干什么用的rn Response.success(body, rawResponse);
}kotlin教程 catch (RuntimeException e) {
// If the uokhttp和retrofitnderlying source thr接口和抽象类的差异ew an exception, pro缓存视频怎样转入本地视频pagate that rather than indicating it wakotlin极简教程s
// a runtime exceptikotlin面试题on.
catchingBody.throwIfCaught();
throw e;
}
}
//re线程sponseConverter 相同也是在OkHttpCall的结构办法中创立的
OkHttpCkotlin极简教程al线程安全l(
RequestFactory requestFactory,
Object[] args,
okhttp3.Call.Factor接口测验面试题y callFactory,
Converter<ResponseBody, T> responseConverter) {
this.requestFactory = requestFactory;
this.args =线程和进程的差异是什么 args;
this线程的概念.callFactory = callFactory;
this.reskotlin下载ponseConverter = responseConverter;
}

所以咱们得持续向上寻找:在HttpServiceM缓存视频兼并app下载ethodparseAnnotatio缓存视频ns办法中回来了reokhttp运用过程sponseConverter

  static <线程池的七个参数ResponseT, ReturnT> HttpServiceMekotlin极简教程thod<ResponseT, ReturnT> parseAnnota线程安全tions(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
.okhttp长处........
ConverKotlinter<ResponseBody, ResponseT> responseConverter =
creKotlinateResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
if (!iskotlin面试题KotlinSuspendFunkotlin下载ction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
.....

咱们来看一下createResokhttp长处ponseConverter办法,调用接口测验retrofit.responseBodyConvkotlin官网erter

private static <Rokhttp运用esponseT> Converter<缓存视频ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method metho接口d, Type responseType) {
Annotatio线程是什么意思n[] annotations = method.getAnnota线程撕裂者tions();
try {
return retrofit.responseBodyConverter(responseType缓存的视频怎样保存到本地, annotations);
} ckotlin怎样读atch (RuntimeException e) { // Wide exceptio线程的几种状况n range be线程安全cause factories接口测验面试题 are user接口的定义 code.
throw methodError(method, e, "Unable to create c缓存视频在手机哪里找onverter for %s", rkotlin实战esponseType);
}
}

代码如下:其实便是去遍接口和抽象类的差异历converterFactories集结,这个集结存储着Converter,下面咱们去找从哪里添加的Cookhttp运用过程nverter

  public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
.......
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPas接口文档t, Type type, Annotatio缓存视频在手机哪里找n[] annotations) {线程池的七个参数
.....
int start = converterFactories.indexOf(skipPast) + 1;
for (int缓存视频变成本地视频 i = start, count = converterFactorieskotlin怎样读.size(); i < count; i++) {
Converter<R线程是什么意思espokotlin为什么盛行不起来nseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(typokhttp运用过程e, annotationskotlin面试题, this);
if (converter缓存的视频怎样保存到本地 != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
}

找到了在Bui接口卡lder中,有一个设置的缓存办法addConverterFa接口自动化ctory

    /** Add converter factory for serialization线程池创立的四种 and deserialization of objects. */
public Builder addConverterFactory(Converter.Factory faokhttp和retrofitctory) {
converterFactories.add(Objects.requireNonNull(factory, "缓存视频变成本地视频factory == null"));
return this;
}

不知道咱们是否还记得在初步的时分运okhttp3源码剖析用Retorfit的进行初始化,看到了没便是它addConverterFactory。咱们添加了GsonConverterFactory便是经过gson去解析json数据转化为设置的javabean类。

val retrofit = Retrofit.Bukotlin面试题ilder()
.baseUrl("http线程的生命周期是什么s://api.github.com/")
.addConverterFact线程和进程的差异是什么ory(GsonConverterFactory.create()) //gson的转化工厂
.build()

OK,那么OkHttpCall的整个流程思路都拾掇清楚了。咱们再看一下流程图。其实咱们从Retrokotlin极简教程fit的源码中能够学习到很多规划办法,学习优异的代码
Retrofit 全面解析

线路D -> adapt

咱们持续回到HttpServiceMetkotlin官网hod的invoke办法,去看adapt的详细结束。

  @接口和抽象类的差异Ov接口类型erride
final @Nullable ReturnT invOKHttpoke(Objeokhttp和retrofitct[] args) {
Call<Respons线程池创立的四种eT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}

如下代码:ad线程是什么意思apt是HttpSer缓存文件在哪里viceMethod的抽象办法

pro线程安全tected abstrackotlin面试题t @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);

那么它是怎样结束的呢?咱们持续回到parseAnnotations 这个办法回来了HttpServerMethod的实例,那么一定结束了adapt抽象办法的。

 if (!isKotli接口自动化nSuspendFunction) { //这儿首要判别 办法是否运用了kotlin的suspenokhttp3d符号,这儿咱们先不关心suspend是干什么的,一般是缓存视频兼并不必suspend的那么就会回来一个CallAdapted
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
....

咱们接着来看CallAdapted的结束, en….. 很乖僻,call缓存视频兼并app下载Adapter是从外部接口测验传递进来的,经过外部传线程池递进来的callAdapterokhttp结构调用adapt办法

  static final class CallAdapted<Responskotlin为什么盛行不起来eT, ReturnT> ex接口自动化tends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttpkotlin为什么盛行不起来3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<R接口自动化esponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.c缓存视频怎样转入本地视频allAdapter = callAdapter;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call)kotlin怎样读;
}
}

咱们还得要持续回到parseAnnotations 能够看到这样的一段代码:

....
CallAdapter<ResponseT, ReturnT>线程池创立的四种 callAdapterkotlin官网 =
createCallAdapter(retrofit, method, adapterType, annotations);
....
if (!isKotlinSuspendFunction) {
return new CallAdapted<线程的概念>(requestFactory, callFactory, res接口的定义ponseConverter, callAdapter);
}
....

原本调用了createCallAdapter办法:诶….缓存视频在手机哪里找 这个办法回来的callAdapter是由retrofit的callAdapter回来的。

  private static <ResponseT, ReturnT> CallA线程是什么意思dapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Ty接口测验pe returnTypokhttp和retrofite, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<Resokhttp运用po线程池的七个参数nseT, ReturnT>) r线程池etrookhttp是干什么用的fit.callAdapter(returnType, annotations线程撕裂者);
} c缓存视频atch (RuntimeExce接口是什么ption e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call a接口卡dapter for %s", returnType);
}
}

持续回到Retrofit,代码如下:其OKHttp实和上述讲的responseBodyConverter 相似能够由运用者自己定义进行设置,咱们能够看到在nextCallAdapter只需遍历的线程池adapter不等于null就会回来中止遍历,接口类型也便是说Retrofit只能有一个CallAdapter,Retrofit必定有一个默许的CallAdapter由于咱们在运用的时分并没有设置它

  pu线程是什么意思blic CallAdapter<?, ?&缓存视频在手机哪里找gt; callAdapter(Type returnType, Annotation[] annotations)缓存 {
return nextCaokhttpclientllAda线程撕裂者pter(null, reOKHttpturnType, annotations);
}
public CallAdapter<?, ?> n线程池创立的四种extCallAdapter(
@Nullable CallAdapter.Factory skipP接口文档ast, Type returnType, Annotation[] ann缓存文件在哪里otations) {
.....
int start = callAdapterFactories.indexOf(skipPast) + 1;
fo接口和抽象类的差异r (int i = start, count =okhttp3 callAdapterFactories.size(); i < count; i++) {
// 获取CallAdapter  
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter !=接口 null) {
return adapter;
}
}
......
}

咱们去Retrofit.Builder.build()办法中查看,代码如下:

public Retrofit build() {
.......
Execokhttp运用utor callbakotlin言语ckExec缓存视频怎样转入相册utor = this.callbackExecutor;
if (callbackExecutookhttp3r == nul接口卡l) {
// 获取线程池 留神platform代线程和进程的差异是什么表的是途径,一般分为Android和Java接口和抽象类的差异  
callbackExecutor = platform.defaultCallbackExecutor();
}
List<CallAdapter.Factory> callA线程dapterFactorieokhttp3源码剖析s = new ArrayList&kotlin极简教程lt;>(this.callAdapterFactories);
callAdapterFactories.add缓存视频兼并All(platform.defaultCallAdapterFactories(callbackEx线程的生命周期是什么ecutor));
.......
}

咱们进入Platform的d线程撕裂者efaultCallAdapterFactories

// 获取platform 根据jvm的nam线程和进程的差异是什么e不同进行获取  
private static Platf缓存视频变成本地视频orm findPl接口crc过错计数atform() {
return "Dalvik".e缓存的视频怎样保存到本地quals(System.getProperty("java.vm.name"))
? new Android()kotlin中心编程 //Kotlin
: new Platform(true);
}
List<? extendkotlin言语s CallAdapter.kotlin怎样读Factory> dekotlin中心编程faultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
DefaultCallAdapteokhttp原理 面试rFactory executorFactory = new DefaultCaokhttp运用llAdapterFactory(callbac接口kExecutor);
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, ex缓存的视频怎样保存到本地ecutorFactory)
: singletonList(executorFactory);
}
// defaultCallbackExecutor的线程池的实施是在主线程中实施的
statkotlin为什么盛行不起来ic final class Android extends Platform {
Android() {
super(Build.VERSION.SDK_INT >= 24);
}
@Override
public Executor defaultCallbackExecutor() {
return new MainThreadExecutkotlin教程or();
}
@Nu线程和进程的差异是什么llable
@Override
Object invokeDefaulokhttp3源码剖析tMethod(
Meokhttp运用thod method, Class<?> declaringClass, Object object, Object... args) throws Throwable {
if (Build.VERSION.SDK_INT < 26) {
throw new UnsupportedOperkotlin官网ationException(
"Calling default methods on API 2接口测验面试题4 and 25 is not supported");
}
return super.invokeDefaultMethod(method, declaringClas接口s, object, args);
}
static final class MainThreadExecutor implements Executor {
// 主线程中的Handler  
private f缓存视频怎样转入本地视频inal Han线程和进程的差异是什么dler handler = new Handler(Looper.getMainLooper());
@Override
public void execute(Runnable r) {
handler.post(r);
}
}
}

再看okhttpclient一下,DefaultCallAdapterFactory,怎样结束CallAdapter的。

final class DefaultCallAdapterFactory e线程池的七个参数x接口tends CallAdapter.Factory {
private fin缓存al @Nullable Executor callkotlin官网backExecutor;
DefaultCallAdapterFactory(@Nullable Executokhttp原理 面试or callbackExecuto缓存视频兼并app下载r) {
this.callbackExecutor = callba接口测验ckExOKHttpecutor;
}
@Override
public @Nullable CallAdapter<?, ?接口是什么> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
//首要判别service 接口办法回来的是Call,假定不是则回来为null 持续循环匹配  
if (getRawType(ret缓存文件在哪里urnType) != Call.class) {
return null;
}
........
// 回来C线程池allAdapterkotlin怎样读的实例 
return new CallAdapter<Object线程池的七个参数, C缓存all线程和进程的差异是什么<?>>() {
@Override
public Type responseType()缓存视频变成本地视频 {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
// 对Call包装
static final class ExecutorCallbackCall<T>okhttp和retrofit implements Call<T> {
finaokhttp是干什么用的l Executor callbackExecutor;
final Call&l缓存视频怎样转入相册t;T> delegate;
// 传递过来一个线程池和delegateCall
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.del缓存视频怎样转入相册egate = delegate;
}
@okhttp运用过程Override
public void enqueue(final Callback<T> callbac接口的定义k) {
....缓存视频怎样转入相册.
delegate.enqueue(
new Callback<T>() {
@Override
public void onResponse(Call<T> call, final Response<T> response) {
//进行线程切换,将回调在主线程中实施  
callbackExecutor.execute(
() -> {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivekotlin官网ring an IOExceptionokhttp3 on
// cancellation.
callback.onFailure(ExecutorCalkotlin怎样读lbackCall.this, new IOException("Canceled"));
} else {
callback.ookhttp结构nResponse(ExecutorCallbackCall.this, response);
}
});
}
.......
});
}
}缓存视频变成本地视频

其实默许的CallAdapter就做了一件事,便是线程切换,在主线程中进行一个回调。
那么kotlin怎样读怎样自定义Call缓存的视频怎样保存到本地Adapter呢线程?咱们知道默许的Retrofit的接口方okhttp运用过程法的回来值为okhttp3源码剖析Call,参与咱们要运用RxJava,怎样适配?

    @GET("users/{user}/repos")
fu线程的概念n listReposRx缓存是什么意思(@Path("user线程") user:String?):Single&l接口是什么t;List<Repo>>
val retrofit = Retrofit.Builder()
.base线程池Url("https://api.github.cookhttp和retrofitm/")
.addConverterFactory(GsonConverterFactory.create()) //gson的转化工厂
.addCallAdapterFactory(RxJava3Ca线程池llAdapterFactory.create())// 添加RxJava支撑kotlin怎样读
.bui线程ld()
retrofit.crea缓存是什么意思te(GitHubService::class.java).listReposRx("octocat")
.subscribe()

那么线程的几种状况RxJavaCallAdapter是怎样匹配RxJava的回来类型的呢?

@Overri接口是什么de
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?okhttpclient> rawType = getRawType(returnType);
//根据他有的回来类型进行匹配的
if (rawTKotlinype == Completable.class) {
// Completable is not parameterized (which is what the rest of this method deals with) so it
// can only be created w线程的概念ith a single configuration.
ret缓存视频怎样转入本地视频urn new RxJava3CallAdapter(
Void.class, scheduler, isAsync, false, true, false, false, false, true);
}
boolean isFlowable = rawokhttp长处Type == Flowable.class;
boolean isSingle = rawType == Sing缓存视频兼并app下载le.class;//咱们上述的比如中就运用的是Single
boolean isMaybe = raw接口卡Type == Maybe.class;接口和抽象类的差异
if (rawType != Ob线程池的七个参数servable.class && !isFlowable && !isSingle &kotlin怎样读& !isMaybe) {
return null;
}
.......
}

OK,那么Retrofit的完好的流程如下,经过线路的办法理清源码。
Retrofit 全面解析