Retrofit源码浅析,大牛教你怎么学习Android多进程

private final Handler handler = new Handler(Looper.getMainLooper());

@Override

public void execute(Runnable r) {

handler.post®;

}

}

}

Android中默认的网络回调执行器为MainThreadExecutor,与主线程Looper的Handler绑定,将网络回调推送到主线程执行。

默认的CallAdapter.Factory为ExecutorCallAdapterFactory对象。CallAdapter.Factory主要适配接口的返回类型,如listRepo的接口方法为:

public interface GitHubService{

@GET(“users/{user}/repos”)

Call<List> listRepos(@Path(“user”) String user);

}

返回为Call< T>类型,Call< T>类型是由ExecutorCallAdapterFactory来适配的,如果在创建Retrofit对象时配置使用RxJava2CallAdapterFactory:

Retrofit retrofit = new Retrofit.Build()

.addCallAdapterFactoryFactory(RxJava2CallAdapterFactory.create())

,build()

那么接口listReops的返回类型可谓Observable< T>。

build最后初始化了转换器工厂类的集合,转换器工厂主要负责网络响应的解析,如果我们设置为GsonConverterFactory,那么就可以使用Gson解析网络结果,如果设置为ProtoConverterFactory,则可以使用ProtoBuf解析网络结果。

2、实现网络接口


在示例中,我们定义了网络接口Githubservice,然后使用创建的Retrofit对象的create方法来实现该接口,网络接口的实现为Retrofit最重要的逻辑,而网络接口的实现就是使用Java的动态代理实现的。create方法的调用和实现如下:

GitHubService githubService = retrofit.create(GitHubService.class);

public T create(final Class service) {

return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },

new InvocationHandler() {

private final Platform platform = Platform.get();

@Override public Object invoke(Object proxy, Method method, Object… args)

throws Throwable {

//创建ServiceMthod对象,完成接口方法的解析和封装

ServiceMethod serviceMethod = loadServiceMethod(method);

OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);

return serviceMethod.callAdapter.adapt(okHttpCall);

}

});

}

Retrofit的create方法的主要逻辑就是返回一个GithubService接口的代理对象。注意这里是代理对象,并不是通过implement关键字实现GithubService接口的实现类,当我们调用代理对象的接口方法时,如调用listRepos方法时:

Call<Lsit> octocat = githubSerivce.listRepos(“octocat”);

就会触发InvocationHandler的invoke方法的调用来完成listRepos接口的实现:返回一个Call< T>对象。

在invoke方法中,调用loadServiceMethod加载一个ServiceMethod对象,如果已经加载过了,则会从缓存中获取,如果没有缓存,则会创建一个新的ServiceMethod对象,在创建过程中完成了对网络接口方法的解析,进而封装成一个ServiceMethod对象。ServiceMethod对象中的成员变量如下:

final class ServiceMethod<R,T>{

final okhttp3.Call.Factory callFactory;

final CallAdapter<R,T> callAdapter;

private final HttpUrl baseUrl;

private final Converter<RespinseBody,R> respinserConverter;

private final String httpMethod; //请求方法:POST GET等

private final String relativeUrl;

private final Headers headers; //请求头

private final MediaType contentType;

}

这些成员变量大部分都是通过解析网络接口方法的注解完成初始化的。在获取到ServiceMethod对象后,使用它完成OkHttpCall< Object>对象的创建。最后通过代码:

return serviceMethod.callAdapter.adapt(okHttpCall);

返回一个对象。这个对象在当前示例下返回的是一个 ExecutorCallbackCall对象,它的创建过程还是比较复杂的,首先serviceMethod中的callAdapter对象是由createCallAdapter创建,而 createCallAdater内部是使用Retrofit对象来获取一个CallAdapter对象,createCallAdapter的调用和实现如下:

public ServiceMethod build() {

callAdapter = createCallAdapter();

}

private CallAdapter<?> createCallAdapter() {

try {

return retrofit.callAdapter(returnType, annotations);

} catch (RuntimeException e) { // Wide exception range because factories are user code.

throw methodError(e, “Unable to create call adapter for %s”, returnType);

}

}

callAdapter方法会遍历CallAdapter.Factory集合adapterFactories,根据网络接口方法的返回值来匹配CallAdapter对象,进而返回对应的CallAdapter。Retrofit的callAdapter方法的实现如下:

//Retrofit.java

public CallAdapter<?> callAdapter(Type returnType, Annotation[] annotations) {

return nextCallAdapter(null, returnType, annotations);

}

public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,

Annotation[] annotations) {

checkNotNull(returnType, “returnType == null”);

checkNotNull(annotations, “annotations == null”);

int start = adapterFactories.indexOf(skipPast) + 1;

//遍历CallAdapter.Factory集合

for (int i = start, count = adapterFactories.size(); i < count; i++) {

//根据网络接口的返回类型匹配相对应的CallAdapter.Factroy,进而获取CallAdapter对象

CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);

if (adapter != null) {

return adapter;

}

}

throw new IllegalArgumentException(builder.toString());

}

之前在创建Retrofit对象的时候,会默认添加一个ExecutorCallAdapterFactroy对象到CallAdapter.Factory的集合中。

所以在遍历CallAdapter.Factroy集合遍历到ExecutorCallAdapterFactory对象时,就会调用该对象的get方法获取一个CallAdapter对象:

//ExecutorCallAdapterFactory.java

@Override

public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {

Class<?> rawType = getRawType(returnType);

// 如果匹配的类型不为Call则返回null

if (rawType != Call.class) {

return null

}

final Type responseType = Utils.getCallResponseType(returnType);

//返回一个CallAdapter对象

return new CallAdapter<Object,Call<?>>{

@Override

public Type responseType(){

return responseType

}

@Override

public Call adapter(Call call){

return new ExecutorCallback<>(callbackExecutor,call);

}

}

}

在get方法中会根据网络接口的返回类型进行匹配,如果返回类型不为Call,则返回null,如果为Call类型,比如网络接口方法listRepos的返回类型为Call,那么就会通过判断来返回一个CallAdapter对象。再回到之前的代码:

serviceMethod.callAdapter.adapter(okHttpCall);

所以serviceMethod.callAdapter实际上是获取的是CallAdapter对象,CallAdapter对象的adapter方法会返回一个ExecutorCallbackCall对象。

所以,如果网络接口的返回类型为Call类型,那么在InvocationHandler的invoke方法中返回对象的类型为ExecutorCallbackCall。

3、网络请求的发送


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后,面试前该准备哪些资源复习?

其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。

这里再分享一下我面试期间的复习路线:(以下体系的复习资料是我从各路大佬收集整理好的)

《Android开发七大模块核心知识笔记》

面试字节两轮后被完虐,字节面试官给你的技术面试指南,请查收

面试字节两轮后被完虐,字节面试官给你的技术面试指南,请查收

《960全网最全Android开发笔记》

面试字节两轮后被完虐,字节面试官给你的技术面试指南,请查收

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值