retrofit2源码分析

CSM中一些常见问题的解决方式 CSM中一些常见问题的解决方式 抖动 摄像机在每帧移动或者旋转时,会产生较严重的抖动问题。 阅读详情

如果对retrofit使用不太了解的可以去网上查一些资料,本篇就直接对源码进行分析了。
一、首先你需要RestfulApi 类,里面声明了咱们的请求

public interface RestfulApi {

    // 获取时间戳
    @POST("app.do?")
    Call<T> getTime(@Query("pattern") String pattern);
}

然后封装Retrofit

public class HttpClient {
    private RestfulApi apiService;
    private OkHttpClient okHttpClient;

    public HttpClient(Context context) {
        okHttpClient = genericClient();
        Retrofit retrofit = new Retrofit.Builder().baseUrl(AppEnvConstants.http_ip)
                .addConverterFactory(GsonConverterFactory.create())
                .client(okHttpClient)
                .build();

        apiService = retrofit.create(RestfulApi.class);
    }

    // 创建OkHttpClient实例
    private OkHttpClient genericClient() {
        return new OkHttpClient.Builder().
                addInterceptor(new HttpInterceptor())
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();
    }
}

然后调用异步接口就是

Call<T> call = apiService.getTime(pattern);
call.enqueue(callback);

二、下边针对retrofit2进行源码分析

// 创建OkHttpClient实例
    private OkHttpClient genericClient() {
        return new OkHttpClient.Builder().
                addInterceptor(new HttpInterceptor())
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();
    }

这一段代码很明显是对OkHttp中OkHttpClient的初始化,对OkHttp不了解可以看下
OkHttp3源码分析

Retrofit retrofit = new Retrofit.Builder().baseUrl(AppEnvConstants.http_ip)
                .addConverterFactory(GsonConverterFactory.create())
                .client(okHttpClient)
                .build();

这一段代码是对Retrofit的初始化

addConverterFactory(GsonConverterFactory.create())//对返回的数据支持json格式解析
client(okHttpClient)//设置okhttp3.Call.Factory callFactory = okHttpClient

最主要的就是下面这段代码

apiService = retrofit.create(RestfulApi.class);

查看源码

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(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 {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {//反射获取到的类全名称
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {//Android/ios返回false,java8返回true
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //组装ServiceMethod,里面有缓存,一样的方法只会执行一次,这个很大程度上优化了性能,因为反射是会消耗性能的
            ServiceMethod serviceMethod = loadServiceMethod(method);
            //传入的serviceMethod和参数
            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

发现上面是典型的Java动态代理
看上面的注释,Android中一定会走到下面,直接分析下面重要代码

ServiceMethod serviceMethod = loadServiceMethod(method);
ServiceMethod loadServiceMethod(Method method) {
    ServiceMethod result;
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);//从缓存中获取serviceMethod
      if (result == null) {
        result = new ServiceMethod.Builder(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

由于动态代理是用的反射的原理,然而所有的反射都有性能消耗,这里对method进行了缓存,每个方法只会运行一次

private final Map<Method, ServiceMethod> serviceMethodCache = new LinkedHashMap<>();

final修饰,引用地址不可变,这里用了LinkedHashMap表示不是很理解,LinkedHashMap底层是链表实现的,哪位朋友知道评论一下

//TODO

ServiceMethod里面的代码暂缓,等下再分析

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

看一下OkHttpCall的构造器

OkHttpCall(ServiceMethod<T> serviceMethod, Object[] args) {
    this.serviceMethod = serviceMethod;
    this.args = args;
  }

只是把刚声明的ServiceMethod和args参数传过去

serviceMethod.callAdapter.adapt(okHttpCall);

三、分析问题
1、serviceMethod.callAdapter是什么?
2、serviceMethod.callAdapter.adapt(okHttpCall)是什么?

先分析一下第一个问题

首先看ServiceMethod的build()里

public ServiceMethod build() {
      callAdapter = createCallAdapter()
private CallAdapter<?> createCallAdapter() {
      Type returnType = method.getGenericReturnType();
      if (Utils.hasUnresolvableType(returnType)) {
        throw methodError(
            "Method return type must not include a type variable or wildcard: %s", returnType);
      }
      if (returnType == void.class) {
        throw methodError("Service methods cannot return void.");
      }
      Annotation[] annotations = method.getAnnotations();
      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);
      }
    }

跑到了Retrofit类里

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;
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);//ExecutorCallAdapterFactory   执行
      if (adapter != null) {
        return adapter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
        .append(returnType)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = adapterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(adapterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }

最后走到了nextCallAdapter里,然后看只是从adapterFactories里取数据,看一下adapterFactories是什么

看一下Retrofit的build

public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
          callbackExecutor, validateEagerly);
    }
  }

重点看一下

Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

看一下Android的Platform

static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

callbackExecutor = platform.defaultCallbackExecutor() = new MainThreadExecutor();
由于MainThreadExecutor里的handler创建的Looper是主线程里的,so handler也是主线程(UI线程)里的,对Android的异步消息机制不了解的可以看下异步消息机制

看到没最后把UI线程赋值给了callbackExecutor

adapterFactories最后add的是ExecutorCallAdapterFactory

然后再回过头来

CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
//等同于
CallAdapter<?> adapter = ExecutorCallAdapterFactory.get(returnType, annotations, this);

看一下ExecutorCallAdapterFactory类

final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
  final Executor callbackExecutor;//MainThreadExecutor 主线程

  ExecutorCallAdapterFactory(Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override
  public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public <R> Call<R> adapt(Call<R> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

  static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

    ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
      this.callbackExecutor = callbackExecutor;//主线程
      this.delegate = delegate;//okhttpCall
    }

    @Override public void enqueue(final Callback<T> callback) {
      if (callback == null) throw new NullPointerException("callback == null");

      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              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<T> call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response<T> execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call<T> clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }
}

回过头来看一下问题
1、serviceMethod.callAdapter是什么?
2、serviceMethod.callAdapter.adapt(okHttpCall)是什么?

答案:
serviceMethod.callAdapter = ExecutorCallAdapterFactory.get(returnType, annotations, this);

callbackExecutor = MainThreadExecutor,这个是retrofit里传进来的

serviceMethod.callAdapter.adapt(okHttpCall) = ExecutorCallAdapterFactory.get(returnType, annotations, this).adapt(okHttpCall) = new ExecutorCallbackCall<>(callbackExecutor, okHttpCall) = new ExecutorCallbackCall<>(MainThreadExecutor, okHttpCall)


回过头来看一下我们业务层写的请求

Call<T> call = apiService.getTime(pattern);
call.enqueue(listener);

call = serviceMethod.callAdapter.adapt(okHttpCall) = new ExecutorCallbackCall<>(MainThreadExecutor, okHttpCall);

call.enqueue(callback) = ExecutorCallbackCall.enqueue(callback)

最后走到了OkHttpCall里,各位看官请看

delegate = OkHttpCall.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              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<T> call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });

搞一段落,终于搞清楚了,最后代码会走到OkHttpCall.enqueue();

分析一下OkHttpCall.enqueue()

@Override public void enqueue(final Callback<T> callback) {
    if (callback == null) throw new NullPointerException("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) {
          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)
          throws IOException {
        Response<T> response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          callFailure(e);
          return;
        }
        callSuccess(response);
      }

      @Override public void onFailure(okhttp3.Call call, IOException e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callSuccess(Response<T> response) {
        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
  }
private okhttp3.Call createRawCall() throws IOException {
    Request request = serviceMethod.toRequest(args);
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);//serviceMethod.callFactory是okhttpClient

    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

ServiceMethod的builder

ServiceMethod(Builder<T> builder) {
    this.callFactory = builder.retrofit.callFactory();

Retrofit里的

    public Builder client(OkHttpClient client) {
      return callFactory(checkNotNull(client, "client == null"));
    }

    /**
     * Specify a custom call factory for creating {@link Call} instances.
     * <p>
     * Note: Calling {@link #client} automatically sets this value.
     */
    public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;
    }

这里面的逻辑其实就是走到了OkHttp里的RealCall.enqueue,然后再解析,回调。
对OkHttp不是很了解可以看下OkHttp源码分析

对源码逻辑明白了,但是想一想设计者为什么要这样设计retrofit,你会学到的更多。

retrofit的设计模式这篇文章写的特别好。
盗用一下图
这里写图片描述

真的是很美妙啊啊……..

PLC期末速成——顺序功能图转梯形图 一、根据顺序功能图写出梯形图程序 顺序功能图: 梯形图: 1、程序段1,系统运行标志M0.0的启-保-停控制电路。 2、程序段2,PLC上电与逆行,初始化脉冲M1.0激活初始化步M2.0。 3、程序段3,当M2.0初始化步为活动步,并且M0.0系统运行标志位为1时,置位M2.1步,复位M2.0步。 4、当M2.1为活动步,并且I0.3中液位传感器为1时,置位M2.2步,复位M2.1步。 5、程序段5,当M2.2为活动步,并且I0.2高液位传感器为1时,置位M2.3步,复位M2.2步。 6、程序段 阅读详情

相关推荐

手把手教你用ADS仿真FMMT417雪崩三极管,搞定射频脉冲源设计

本文详细介绍了如何使用ADS仿真工具设计基于FMMT417雪崩三极管的射频脉冲源。从器件选型、SPICE模型导入到电路设计与优化,提供了一套完整的实操方案,特别适合射频脉冲设计的初学者。通过级联设计和实测验证,帮助工程师快速掌握雪崩电路的应用技巧,提升射频脉冲源的设计效率。

weixin_30905981的博客 488

Retrofit源码分析

Retrofit是对OKHttp的封装,简化了网络请求。具体使用参见官方文档。本文从一次完整的同步请求分析源码,跟着源码一起阅读,肯定会有收获的。分析的版本是retrofit-2.1.0。 支持原创,转载请注明出处。 老规矩,先上图。 类图 Retrofit.png 实例 public class LearnRetrofit { public static fina

u012845099的博客 655

C# ArcGIS Engine二次开发——实现“加载shp文件”

private void AddShpDataToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog OpFileDialog=new OpenFileDialog();//OpenFileDialog:打开文件对话框 OpFileDialog.Title="添加矢量数据"; OpFileDialog.Filter="(*.shp)|*.shp";//filter:过滤器;"(*.shp)|*.shp"

weixin_42191203的博客 5254

Unable to create call adapter for rx.Observable<java.lang.String> retrofit2+rxjava3配置运行报错

当retrofit2与rxjava3连用时(截止发博客时间,很多搜索结果还是retrofit2+rxjava2,而retrofit2+rxjava3的还是比较少的,所以特此记录一下),按照常规的写法,在运行时会报错:Unable to create call adapter for rx.Observable<java.lang.String> 先看一下发生错误的配置是: dependencies { implementation fileTree(dir: "libs", incl

qq_33539839的博客 1162

研究生课程笔记:软件包在流行病学中的应用(三)——STATA软件

关键词:STATA软件基本操作、STATA对于流行病学研究的实现、STATA对复杂抽样设计样本量计算的实现 一、STATA软件基本操作 这部分网上教程有很多,也可以直接根据stata自带的help功能进行自学,在此只记录课程中提及的功能项。 1. 变量编辑 1.1 赋值:label type(按精度区分) 1) 整型:int(32), short(16), long(32) 2) 实型:flo...

weixin_45463530的博客 2432

Drools vs URule:5个真实项目场景告诉你如何选择开源规则引擎

本文通过电商风控、物流计费、会员体系、保险定价和物联网告警五个真实项目场景,深度对比了Drools与URule两款开源规则引擎。分析了两者在规则复杂度、性能表现、开发运维及适用场景上的核心差异,为技术选型提供基于实战的决策指南。

k6l7m8n9的博客 943

修复Android更新AGP8后retrofit2混淆出现错误:Unable to create call adapter for interface retrofit2.Call,并附上完整混淆规则

修复Android更新AGP8后retrofit2混淆出现错误:Unable to create call adapter for interface retrofit2.Call,并附上完整混淆规则

s894792409的博客 2367

ESP32小车DIY:从零搭建无线遥控智能车(附完整代码与避坑指南)

本文详细介绍了如何从零开始DIY一台基于ESP32的无线遥控智能小车。内容涵盖核心硬件选型、电路设计、低延迟ESP-NOW无线通信协议的配置与实战,以及双电机差速控制算法与PWM调速的实现。文章提供了完整的代码示例和关键的避坑指南,旨在帮助开发者快速构建稳定可靠的智能车平台,并为进一步的功能扩展奠定基础。

gamma的博客 469

java.lang.IllegalArgumentException: Unable to create call adapter for class java.lang.Object

使用Kotlin 协程 和retrofit +okhttp suspend网络请求时,会出现java.lang.IllegalArgumentException: Unable to create call adapter for class java.lang.Object 修复: 将Retrofit 相关版本升级即可!

专注Android ,直到世界尽头 1815

PX4与ROS协同仿真:从键盘控制到无人机自主飞行

本文详细介绍了如何搭建PX4与ROS协同仿真环境,实现从键盘控制到无人机自主飞行的完整流程。通过XTDrone项目整合PX4飞控、ROS通信框架与Gazebo物理引擎,逐步讲解环境配置、键盘控制实现原理,并深入剖析了迈向Offboard模式实现自主飞行的核心代码与数据流,为无人机算法开发与测试提供了安全的仿真沙盒。

weixin_29169899的博客 498

Python 爬虫实战:爬取万方数据文献信息

本文介绍了基于Python爬虫技术合规获取万方数据文献信息的方法。通过分析万方数据的请求机制与反爬策略,采用requests库结合Session维持合法会话,实现了文献标题、摘要、作者等核心元数据的提取。文章详细讲解了Token验证、动态请求构造、JSON数据解析等关键技术,并提供了完整可运行代码。同时强调严格遵守《万方数据知识服务平台用户协议》,控制请求频率,仅限学术研究使用。该方案为万方数据文献信息获取提供了标准化解决方案,支持数据清洗、结构化存储及后续分析应用。

2503_91057718的博客 2135

rxjava2 + retrofit2 + okhttp3遇到的问题

上代码: //手动创建一个OkHttpClient并设置超时时间 OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder(); httpClientBuilder.connectTimeout(3, TimeUnit.SECONDS); httpClientBuilder.readTimeout(2, TimeUni

快慢机的地盘 4429

【SpringBoot 3.x 第92节】Spring Modulith:构建模块化单体架构(基于 Spring Boot 3),一文带你搞透(超详细)!

🏆本文收录于《滚雪球学SpringBoot 3.x》,专门攻坚指数提升,本年度国内最系统+最专业+最详细(永久更新)。    该专栏致力打造最硬核 SpringBoot3 从零基础到进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。 如果想快速定位学习,可以看这篇【SpringBoot3教程导航帖】,你想学习的都被收集在内,快速投入学习!!两不误。

**My Coding Family** 998

Android进阶之Retrofit2的基本使用及源码分析

一、前言 Retrofit框架在项目开发中一直有用到,但是对其一些原理还不是很明白,所以在这做个梳理。 二‘、retrofit的使用 首先,在GitHub上查看最新的版本,然后添加库的依赖 三、retrofit的问题分析 四、 ...

qq_33613491的博客 348

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Retrofit 2.x上传文件的两种方式及源码分析

Retrofit 2.x上传文件的两种方式及源码分析

Civitasv 1106

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Android:这是一份全面-&-详细的Retrofit-2-0-源码分析指南

定义:网络请求执行器(Call)的适配器Call在Retrofit里默认是OkHttpCall在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory作用:将默认的网络请求执行器(OkHttpCall)转换成适合被不同平台来调用的网络请求执行器形式如:一开始Retrofit。

1158

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Retrofit2源码分析

一、概述     在了解Retrofit2源码架构之前先说明,本文默认读者对Retrofit2框架的使用有一定了解,除此之外还要先熟悉okhttp3框架和Java代理模式中的动态代理,不然后面咱们看Retrofit2源码时会很难理解:     Java代理模式     严格地说,Retrofit2并不是一个网络请求交易框架,它只是对网络请...

qq_32534441的博客 333

Retrofit2 源码分析

Retrofit源码执行过程分析

qq1302526289的博客 430

Retrofit 2.5 框架使用与源码分析

Retrofit 2.5 框架使用与源码分析 Retrofit 框架使用 请求内容与返回值 使用PostMan进行请求测试 请求:https://api.github.com/search/repositories?q=android 返回值: Header: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jfcpcmls-1575109634293)(/asset...

Lucius的博客 365

Retrofit2源码分析:架构全面解析

目录   一、概述 二、Retrofit2源码地址 三、Retrofit2简单使用 四、架构流程 1、流程图 2、流程讲解 五、源码分析 1、Retrofit的内部成员变量 2、Retrofit内部类Builder 3、创建Retrofit实例 4、Builder.build()方法 5、retrofit.create() 6、loadServiceMethod() ...

欢迎来到Cozing的博客 6020
上一篇: 二分查找、折半查找
下一篇: Kotlin在Android studio上的环境配置和运用(一)
豪豪6
博客等级 码龄14年 6粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值