简介

Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的。
在gradle中添加

compile 'com.squareup.retrofit2:retrofit:2.3.0'    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
实现简单的POST请求
  1. 首先创建业务接口,代码如下
public interface LoginService {    @POST("user/auth")    Call login(@Query("username") String username, @Query("password") String password);}

这里对几种类型的注解做下说明:
@GET 和@POST分别对应get和post请求
@Query代表请求参数,另外还有@Body,@Field,@Part,@Path,@Header等注解

2.完成LoginService的配置

Retrofit retrofit = new Retrofit.Builder()                .baseUrl(baseUrl)                .addConverterFactory(GsonConverterFactory.create())                .build();   LoginService loginService = retrofit.create(LoginService.class);

3.调用接口方法,完成请求

Call<User> call = loginService.login("nanguangtailang","123");        call.enqueue(new Callback<User>() {            @Override            public void onResponse(Call<User> call, Response<User> response) {                Log.d("d",response.body().toString());            }           @Override            public void onFailure(Call<User> call, Throwable t) {                Log.d("f",t.getMessage());            }        });

到这里我们的第一次简单使用Retrofit之旅已经结束了,接下来我们看看Retrofit关键实现的源码(主要关注第二步中出现的类和方法)
在创建Retrofit实例使用了builder模式,Builder是Retrofit中的一个嵌套类,代码如下

public static final class Builder {    private final Platform platform;    private @Nullable okhttp3.Call.Factory callFactory;    private HttpUrl baseUrl;    private final List converterFactories = new ArrayList<>();    private final List adapterFactories = new ArrayList<>();    private @Nullable Executor callbackExecutor;    private boolean validateEagerly;    Builder(Platform platform) {      this.platform = platform;      // 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());    }    public Builder() {      this(Platform.get());    }

可以看到这个类中的几个重要属性 Platform、okhttp3.Call.Factory、List< Converter.Factory >、List< CallAdapter.Factory > 、Executor
platform 代表我们目前使用的平台,Android、iOS等 ,okhttp3.Call.Factory 是我们传入的 okhttpClient,作用是代理Retrofit发出http请求

接下来我们看看

 LoginService loginService = retrofit.create(LoginService.class);

这行代码执行时发生了什么
这是create()方法的内部实现

public  T create(final Class 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, @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);            }            if (platform.isDefaultMethod(method)) {              return platform.invokeDefaultMethod(method, service, proxy, args);            }            ServiceMethod serviceMethod =                (ServiceMethod) loadServiceMethod(method);            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);            return serviceMethod.callAdapter.adapt(okHttpCall);          }        });  }   

这个方法中最重要的就是

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

这里就必须要提到java的动态代理机制了,可以通过代理模式来理解java的动态代理

代理模式是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个真实对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理

关于动态代理的具体细节可以参考Java动态代理的使用及原理分析
现在我们知道了实际执行的代码是

@Override public 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);            }            if (platform.isDefaultMethod(method)) {              return platform.invokeDefaultMethod(method, service, proxy, args);            }            ServiceMethod<Object, Object> serviceMethod =                (ServiceMethod) loadServiceMethod(method);            OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);            return serviceMethod.callAdapter.adapt(okHttpCall);          }   

如果我们传入的参数没有错误的话,应该会执行到此方法的最后三行
倒数第二行获得了OkHttpCall类,最后一行将okHttpCall装饰成ExecutorCallbackCall类,然后再返回给调用程序。
其实看到这里我们已经能够发现请求已经被委托给了OkHttpCall,我们在看下OkHttpCall类的内部实现

final class OkHttpCall implements Call {  private final ServiceMethod serviceMethod;  private final @Nullable Object[] args;  private volatile boolean canceled;  @GuardedBy("this")  private @Nullable okhttp3.Call rawCall;  @GuardedBy("this")  private @Nullable Throwable creationFailure; // Either a RuntimeException or IOException.  @GuardedBy("this")  private boolean executed;  OkHttpCall(ServiceMethod serviceMethod, @Nullable Object[] args) {    this.serviceMethod = serviceMethod;    this.args = args;  }  @SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.  @Override public OkHttpCall clone() {    return new OkHttpCall<>(serviceMethod, args);  }  @Override public synchronized Request request() {    okhttp3.Call call = rawCall;    if (call != null) {      return call.request();    }    if (creationFailure != null) {      if (creationFailure instanceof IOException) {        throw new RuntimeException("Unable to create request.", creationFailure);      } else {        throw (RuntimeException) creationFailure;      }    }    try {      return (rawCall = createRawCall()).request();    } catch (RuntimeException e) {      creationFailure = e;      throw e;    } catch (IOException e) {      creationFailure = e;      throw new RuntimeException("Unable to create request.", e);    }  }  @Override public void enqueue(final Callback callback) {    checkNotNull(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) {          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 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 response) {        try {          callback.onResponse(OkHttpCall.this, response);        } catch (Throwable t) {          t.printStackTrace();        }      }    });  }  @Override public synchronized boolean isExecuted() {    return executed;  }  @Override public Response execute() throws IOException {    okhttp3.Call call;    synchronized (this) {      if (executed) throw new IllegalStateException("Already executed.");      executed = true;      if (creationFailure != null) {        if (creationFailure instanceof IOException) {          throw (IOException) creationFailure;        } else {          throw (RuntimeException) creationFailure;        }      }      call = rawCall;      if (call == null) {        try {          call = rawCall = createRawCall();        } catch (IOException | RuntimeException e) {          creationFailure = e;          throw e;        }      }    }    if (canceled) {      call.cancel();    }    return parseResponse(call.execute());  }  private okhttp3.Call createRawCall() throws IOException {    Request request = serviceMethod.toRequest(args);    okhttp3.Call call = serviceMethod.callFactory.newCall(request);    if (call == null) {      throw new NullPointerException("Call.Factory returned null.");    }    return call;  }  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);    }    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);    try {      T body = serviceMethod.toResponse(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;    }  }  public void cancel() {    canceled = true;    okhttp3.Call call;    synchronized (this) {      call = rawCall;    }    if (call != null) {      call.cancel();    }  }  @Override public boolean isCanceled() {    if (canceled) {      return true;    }    synchronized (this) {      return rawCall != null && rawCall.isCanceled();    }  }  static final class NoContentResponseBody extends ResponseBody {    private final MediaType contentType;    private final long contentLength;    NoContentResponseBody(MediaType contentType, long contentLength) {      this.contentType = contentType;      this.contentLength = contentLength;    }    @Override public MediaType contentType() {      return contentType;    }    @Override public long contentLength() {      return contentLength;    }    @Override public BufferedSource source() {      throw new IllegalStateException("Cannot read raw response body of a converted body.");    }  }  static final class ExceptionCatchingRequestBody extends ResponseBody {    private final ResponseBody delegate;    IOException thrownException;    ExceptionCatchingRequestBody(ResponseBody delegate) {      this.delegate = delegate;    }    @Override public MediaType contentType() {      return delegate.contentType();    }    @Override public long contentLength() {      return delegate.contentLength();    }    @Override public BufferedSource source() {      return Okio.buffer(new ForwardingSource(delegate.source()) {        @Override public long read(Buffer sink, long byteCount) throws IOException {          try {            return super.read(sink, byteCount);          } catch (IOException e) {            thrownException = e;            throw e;          }        }      });    }    @Override public void close() {      delegate.close();    }    void throwIfCaught() throws IOException {      if (thrownException != null) {        throw thrownException;      }    }  }}

其实OkHttpCall就是封装了okHttp的实现,所以retrofit最终的请求时由okhttp发起的。

更多相关文章

  1. Android(安卓)Json解析方法
  2. bitmap设置图片尺寸缩小,避免内存溢出/OutOfMemoryError的优化方
  3. Android反射机制实现与原理
  4. android ListView显示网络图片
  5. Android(安卓)Handler 用法解析
  6. Android面试常客之Handler全解
  7. Android(安卓)ProGuard技术详解
  8. 实现TabWidget选项卡按钮在屏幕下方
  9. Android(安卓)通过反射调用获取内置存储和外置sd卡根路径(适用于

随机推荐

  1. Android无法解锁debug
  2. Selector、shape详解(一)
  3. Android(安卓)如何开发 Bottom Navigatio
  4. 在android中policymanager
  5. android dialog 动画
  6. 【Android】文件读写操作(含SDCard的读写)
  7. Android——Activity四种启动模式
  8. Android(安卓)Settings
  9. Android(安卓)View的介绍和使用
  10. Hello Android(安卓)- android窗体透明的