当前位置: 首页 > news >正文

网站建设销售是做什么的网站怎么做分类聚合

网站建设销售是做什么的,网站怎么做分类聚合,做金融网站,废品回收网站怎么做网站优化文章目录一、Retrofit简介二、使用介绍2.1 app / build.gradle添加依赖2.2 创建 Retrofit 实例2.3 创建 API 接口定义文件2.4 使用 Retrofit 进行网络请求三、源码分析3.1 创建 Retrofit 实例: 建造者模式创建Retrofit3.2 实例化API接口: 动态代理模式3.3 获取Observable返回值… 文章目录一、Retrofit简介二、使用介绍2.1 app / build.gradle添加依赖2.2 创建 Retrofit 实例2.3 创建 API 接口定义文件2.4 使用 Retrofit 进行网络请求三、源码分析3.1 创建 Retrofit 实例: 建造者模式创建Retrofit3.2 实例化API接口: 动态代理模式3.3 获取Observable返回值3.3.1 ServiceMethod.java3.3.2 HttpServiceMethod.java3.3.3 HttpServiceMethod.java3.3.4 CallAdapted.java3.3.5 RxJava3CallAdapter.java3.4 发起网络请求3.4.1 CallEnqueueObservable.java3.4.2 OkHttpCall.java3.4.3 GsonResponseBodyConverter.java四、参考文档一、Retrofit简介 square/retrofit Github地址 最新版本从这里获取! Retrofit 是一款由 Square 公司开发的用于 Android 和 Java 应用程序的网络请求库旨在简化 HTTP 网络请求的过程Retrofit 最初是在 2013 年开源发布的已经风靡了10年。其优点如下 简化网络请求的过程Retrofit 可以根据 API 接口定义文件自动生成网络请求代码从而避免了手动创建网络请求代码的繁琐工作。方便处理网络请求Retrofit 支持使用注解如 GET、POST 等来指定网络请求的方法和参数同时支持异步网络请求和回调处理方便处理网络请求和响应。易于定制和扩展Retrofit 提供了一些定制和扩展机制如自定义网络请求和响应处理器、支持多种转换器如 JSON 转换器、XML 转换器等等可以满足不同的网络请求需求支持缓存Retrofit 支持网络请求结果的缓存可以在没有网络连接时提供离线数据访问的功能基于 OkHttpRetrofit 是基于 OkHttp 实现的OkHttp 是一个高效、灵活和易于使用的网络请求库因此 Retrofit 也具有 OkHttp 的优点如连接池、请求队列等 二、使用介绍 2.1 app / build.gradle添加依赖 dependencies {implementation com.squareup.retrofit2:retrofit:2.9.0implementation com.squareup.retrofit2:converter-gson:2.9.0// 下面三个是rxjava相关的依赖如果你的项目不使用rxjava可以不用依赖// 注意adapter-rxjava3,如果你的rxjava版本是2,那这里是adapter-rxjava2这个自己网上找吧implementation com.squareup.retrofit2:adapter-rxjava3:2.9.0implementation io.reactivex.rxjava3:rxandroid:3.0.2implementation io.reactivex.rxjava3:rxjava:3.1.5 }2.2 创建 Retrofit 实例 Retrofit retrofit new Retrofit.Builder().baseUrl(https://api.example.com/).addCallAdapterFactory(RxJava3CallAdapterFactory.create()) // rxjava call.addConverterFactory(GsonConverterFactory.create()) // json解析.build() 2.3 创建 API 接口定义文件 具体如何定义可以参考Retrofit 官方文档介绍学习相关注解的使用方法 public interface IService {GET(app/update)ObservableInteger getUpdateInfo();GET(app/test)CallInteger getTestInfo(); }2.4 使用 Retrofit 进行网络请求 IService apiService retrofit.create(IService.class);apiService.getUpdateInfo().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new ObserverInteger() {Overridepublic void onSubscribe(NonNull Disposable d) {}Overridepublic void onNext(NonNull Integer integer) {}Overridepublic void onError(NonNull Throwable e) {}Overridepublic void onComplete() {}});}三、源码分析 通过上面四步我们可以使用Retrofit发起一个完整的网络请求, 接下来让我们学习一下源码 3.1 创建 Retrofit 实例: 建造者模式创建Retrofit Retrofit.java Retrofit retrofit new Retrofit.Builder().baseUrl(BASE_URL).addCallAdapterFactory(RxJava3CallAdapterFactory.create()).addConverterFactory(GsonConverterFactory.create()).build();Retrofit.java 的 Retrofit.Builderpublic Retrofit build() {if (baseUrl null) {throw new IllegalStateException(Base URL required.);}// 对应 Builder.client() 如果你赋值的话这里就不会为nullokhttp3.Call.Factory callFactory this.callFactory;if (callFactory null) {// 没有定义的话默认使用OkHttpClientcallFactory new OkHttpClient();}// 对应 Builder.callbackExecutor(), 如果你赋值的话这里就不会为nullExecutor callbackExecutor this.callbackExecutor;if (callbackExecutor null) {// platform 是Android, defaultCallbackExecutor() -- new MainThreadExecutor()// MainThreadExecutor 创建一个主线程的Looper Handler,当异步任务处理完毕会把结果通过post的方式发到主线程callbackExecutor platform.defaultCallbackExecutor();}// 对应 Builder.addCallAdapterFactory(), 我们使用了RxJava3CallAdapterFactory.create() --// RxJava3CallAdapterFactoryListCallAdapter.Factory callAdapterFactories new ArrayList(this.callAdapterFactories);// java8 开始新增 CompletableFutureCallAdapterFactory DefaultCallAdapterFactory// java8 以下只有 DefaultCallAdapterFactorycallAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));ListConverter.Factory converterFactories new ArrayList(1 this.converterFactories.size() platform.defaultConverterFactoriesSize());converterFactories.add(new BuiltInConverters());// 对应 Builder.addConverterFactory(), 我们使用了GsonConverterFactory.create() -- GsonConverterFactoryconverterFactories.addAll(this.converterFactories);converterFactories.addAll(platform.defaultConverterFactories());return new Retrofit(callFactory,baseUrl,unmodifiableList(converterFactories),unmodifiableList(callAdapterFactories),callbackExecutor,validateEagerly);}}目前Retrofit的相关信息已配置完毕 Retrofit(okhttp3.Call.Factory callFactory,HttpUrl baseUrl,ListConverter.Factory converterFactories,ListCallAdapter.Factory callAdapterFactories,Nullable Executor callbackExecutor,boolean validateEagerly) {this.callFactory callFactory;this.baseUrl baseUrl;this.converterFactories converterFactories; // Copyunmodifiable at call site.this.callAdapterFactories callAdapterFactories; // Copyunmodifiable at call site.this.callbackExecutor callbackExecutor;this.validateEagerly validateEagerly;}3.2 实例化API接口: 动态代理模式 IService apiService retrofit.create(IService.class);多年前分析Retrofit源码的时候我也很懵逼, 啥是动态代理? 为啥要用动态代理? 从官方的介绍或者其他博主人云亦云的观点把我搞得一头雾水其实这个问题很简单不是因为动态代理才有需求而是因为需求才有动态代理 假设你是Retrofit的开发人员, 现在使用Retrofit的人都会给你传参数(url,requestMethod,header,params), 你该怎么设计框架才可以拿到用户的参数? 大部分人的第一反应就是: 暴露个方法呗 那要是参数可变呢重载 那url散落代码各处梳理不便呢em… 聪明的你开始想到了注解创建一个网络请求接口A里面每个方法对应每个网络请求方法的注解对应着需要的参数再创建一个实现类Aimpl在Aimpl的每个方法中去反射获取A对应方法的注解然后去发起请求。 我们继续思考一下Aimpl除了解析不同的方法外基本上内容完全相同如果存在接口ABCD是不是还得对应生成Aimpl Bimpl Cimpl Dimpl这样的实现类有没有什么办法可以再优化一下 有 这就是动态代理 篇幅有限这里就不展开动态代理的官方介绍了有兴趣的同学可以自行查询下。 public T T create(final ClassT service) {// 这里会校验这个class是不是接口,不是接口就会直接抛异常validateServiceInterface(service);// Proxy.newProxyInstance 动态代理典型用法, 内部通过newInstance反射创建一个实例return (T)Proxy.newProxyInstance(service.getClassLoader(),new Class?[] {service},// 这个InvocationHandler相当于一个Hook只要你调用了这个实例的方法都会回调invokenew InvocationHandler() {private final Platform platform Platform.get();private final Object[] emptyArgs new Object[0];Overridepublic Nullable Object invoke(Object proxy, Method method, Nullable Object[] args)throws Throwable {// 如果是Object类的话就不hook了执行Object的方法吧if (method.getDeclaringClass() Object.class) {return method.invoke(this, args);}args args ! null ? args : emptyArgs;// platform 是Android, isDefaultMethod 判断这个接口的方法是不是default方法, Java8开始支持接口内增加有实现体的 default方法这里的意思是: 我只拦截没有实现的方法有实现体的方法不会拦截return platform.isDefaultMethod(method)? platform.invokeDefaultMethod(method, service, proxy, args)// loadServiceMethod 是重头戏的开始,等会继续分析: loadServiceMethod(method).invoke(args);}});}3.3 获取Observable返回值 apiService.getUpdateInfo() -- 触发上文提到的 loadServiceMethodServiceMethod? loadServiceMethod(Method method) {// retrofit不会无脑create一次反射一次也会有缓存机制的ServiceMethod? result serviceMethodCache.get(method);if (result ! null) return result;synchronized (serviceMethodCache) {result serviceMethodCache.get(method);if (result null) {result ServiceMethod.parseAnnotations(this, method);serviceMethodCache.put(method, result);}}return result;}3.3.1 ServiceMethod.java static T ServiceMethodT parseAnnotations(Retrofit retrofit, Method method) {// 对注解的校验解析headers,method,baseUrl,contentType 等信息RequestFactory requestFactory RequestFactory.parseAnnotations(retrofit, method);// ....return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);}3.3.2 HttpServiceMethod.java 这里有对Kotlin suspend函数的处理以后再讲我们还是分析Java的流程 static ResponseT, ReturnT HttpServiceMethodResponseT, ReturnT parseAnnotations(Retrofit retrofit, Method method, RequestFactory requestFactory) {// ....// 结合3.1 创建Retrofit实例的代码 // Retrofit.callAdapter -- Retrofit.nextCallAdapter -- callAdapterFactories.get().get()// -- RxJava3CallAdapterCallAdapterResponseT, ReturnT callAdapter createCallAdapter(retrofit, method, adapterType, annotations);// Retrofit.responseBodyConverter -- Retrofit.nextResponseBodyConverter -- converterFactories.responseBodyConverter -- GsonResponseBodyConverterConverterResponseBody, ResponseT responseConverter createResponseConverter(retrofit, method, responseType);// callFactory 默认OkHttpClientokhttp3.Call.Factory callFactory retrofit.callFactory;if (!isKotlinSuspendFunction) {// 回到3.2 loadServiceMethod(method)最终返回的是 CallAdapted, 而CallAdapted没有实现invoke方法而是其父类HttpServiceMethod实现return new CallAdapted(requestFactory, callFactory, responseConverter, callAdapter);} else{//.....}}3.3.3 HttpServiceMethod.java Overridefinal Nullable ReturnT invoke(Object[] args) {// OkHttpCall是Retrofit对OkHttp的包装CallResponseT call new OkHttpCall(requestFactory, args, callFactory, responseConverter);return adapt(call, args);}// adapt是抽象方法,具体实现还是交给了CallAdapted protected abstract Nullable ReturnT adapt(CallResponseT call, Object[] args);3.3.4 CallAdapted.java Override protected ReturnT adapt(CallResponseT call, Object[] args) {// 3.3.2 提到 callAdapter 就是 RxJava3CallAdapterreturn callAdapter.adapt(call);}3.3.5 RxJava3CallAdapter.java Overridepublic Object adapt(CallR call) {// 由于我们使用的 RxJava3CallAdapterFactory.create() 默认 isAsync 传了true所以这里最终返回的就是 CallEnqueueObservableObservableResponseR responseObservable isAsync ? new CallEnqueueObservable(call) : new CallExecuteObservable(call);// ... } else {observable responseObservable;}// ...return RxJavaPlugins.onAssembly(observable);} }所以 apiService.getUpdateInfo() 最终返回的是 CallEnqueueObservable 3.4 发起网络请求 我在Rxjava线程切换原理终于在2023年有了答案这篇博客中提到Rxjava最重要的一个环节就是subscribe, 正是有了这个环节才会产生 订阅流和回调流 // 直接去看 CallEnqueueObservable 的 subscribeActual , 这里如果跟不上的话可以去看一下我的Rxjava的博客 apiService.getUpdateInfo().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new ObserverInteger() {Overridepublic void onSubscribe(NonNull Disposable d) {}Overridepublic void onNext(NonNull Integer integer) {}Overridepublic void onError(NonNull Throwable e) {}Overridepublic void onComplete() {}});3.4.1 CallEnqueueObservable.java Overrideprotected void subscribeActual(Observer? super ResponseT observer) {// Since Call is a one-shot type, clone it for each new observer.CallT call originalCall.clone();// 根据 3.3.3 call就是OkHttpCallCallCallbackT callback new CallCallback(call, observer);observer.onSubscribe(callback);if (!callback.isDisposed()) {// 真正发起网络请求的地方开始了call.enqueue(callback);}}3.4.2 OkHttpCall.java Overridepublic void enqueue(final CallbackT callback) {// ...call rawCall createRawCall();// ....call.enqueue(new okhttp3.Callback() {Overridepublic void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {//...response parseResponse(rawResponse);callback.onResponse(OkHttpCall.this, response);//...}Overridepublic void onFailure(okhttp3.Call call, IOException e) {callFailure(e);}});}private okhttp3.Call createRawCall() throws IOException {// 结合代码 3.3.2 callFactory 其实就是 OkHttpClient -- RealCall.newRealCall 这里就进入了OkHttp的代码以后还会分析OKHttp这里就到此为止okhttp3.Call call callFactory.newCall(requestFactory.create(args));if (call null) {throw new NullPointerException(Call.Factory returned null.);}return call;}ResponseT parseResponse(okhttp3.Response rawResponse) throws IOException {// ... 这会处理code码比如 code 200 || code 300 code 204 || code 205等// 根据3.3.2 responseBodyConverter -- GsonResponseBodyConverter 就是这里的 responseConverterT body responseConverter.convert(catchingBody);// ...}3.4.3 GsonResponseBodyConverter.java Overridepublic T convert(ResponseBody value) throws IOException {// Json解析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();}}拿到请求结果后再根据RxJava的回调流回调给订阅者完成整个请求的全部流程 四、参考文档 Retrofit 源码分析 一定能看懂的 Retrofit 最详细的源码解析 Android 网络框架之Retrofit源码解析 【面试 反思】Retrofit源码与设计 7 连问
http://www.hkea.cn/news/14416491/

相关文章:

  • 找个免费的网站这么难吗茶楼 网站
  • 代做ppt网站什么是网络设计与电子商务
  • 岳阳网站建设与设计搜索引擎优化分析
  • 去国外做外卖网站企业申请网站建设请示
  • h5可以制作公司网站吗网站悬浮框代码
  • 用四字成语做网站域名好吗acg二次元wordpress主题
  • 做音乐网站要什么源码可以个人做单的猎头网站
  • 北京高端it网站建设网站开发加设计要多少钱
  • 做企业网站申请域名wordpress获取页面标题
  • 网站空间后台怎么进入wordpress视频无法播放视频播放器
  • wap网站建设是什么好听高雅又聚财的公司名字
  • 做外贸的网站域名怎么买福田我要做网站优化比较好
  • asp.net网站不能上传图片网站开发所需能力
  • 晋城网站建设公司优质友情链接
  • 怎么做网站官方电话番禺区pc端网站建设
  • 自己能建设网站吗物流运输 有哪些网站可以做推广
  • 电子商务网站建设与运营方向静安制作企业网站
  • 怎么在vps上做网站河北网站备案 多长时间通过
  • 货源网站网站开发和网络工程哪个好
  • 微信推广网站建设媒介平台
  • 红安建设局投诉网站桐城做网站的公司
  • 南京中建乡旅建设投资有限公司网站保健品网站建设
  • 学校资源网站的建设方案做水果的有什么网站好
  • 做营销型网站用什么技术佛山专业网站建设公司哪家好
  • 网站运营技术性高吗wordpress在php7.0
  • 沈阳制作网站的公司有哪些班级网站建设的参考文献
  • 企业官方网站系统建设怎么样让网站网址有图标
  • 模块化网站建设2017我们一起做网站
  • 集团网站建设推广网站平台
  • 建设银行网站注销吗如何创新网站建设模式