Retrofit是对okhttp的包装, 先看下简单使用:
1, 引入依赖
1 implementation 'com.squareup.retrofit2:retrofit:2.9.0' 2 implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
这里的converter-gson是接收到response后做gson解析用的
2, 定义一个service接口, 使用注解的方式声明请求方法,参数等
1 interface MyService { 2 3 @GET("users/{user}/repos") 4 fun testGet(@Path("user") user : String): Call<ResponseData> 5 }
3, 创建retrofit
1 val retrofit = Retrofit.Builder() 2 .baseUrl("https://www.baidu.com") 3 .addConverterFactory(GsonConverterFactory.create()) 4 .build()
4, 通过retrofit.create()方法创建出service的实例
1 val service = retrofit.create(MyService::class.java) 2
5, 通过这个service实例创建一个可以用来发起网络请求的Call对象
1 val call: Call<ResponseData> = service.testGet("zhangsan")
6, call.enqueue(callback)执行网络请求, 这里也可以用call.execute(), 区别在于enqueue是异步的
1 call.enqueue(object : Callback<ResponseData>{ 2 override fun onResponse(call: Call<ResponseData>, response: Response<ResponseData>) { 3 println(response.body()?.name) 4 } 5 6 override fun onFailure(call: Call<ResponseData>, t: Throwable) { 7 t.printStackTrace() 8 } 9 })
Retrofit源码概述:
1, create()方法主要做了两件事,
首先验证我们传进去的这个service是不是个接口,不是就抛异常,
以及这个接口及其父接口是不是包含了泛型(java8的特性), 如果是就会抛出异常
以及接口里的方法是不是静态方法(java8), 接口里的方法是不是有默认实现(java8)
其次,通过动态代理的方式生成一个service接口的实现
(代理: 简单来说, 比如一个类实现了某个接口, 那么我们就说这个类是这个接口的代理。 所谓动态代理就是说,这个实现类并不是我们预先写好的, 而是在程序运行期间动态去生成的。)
1 public <T> T create(final Class<T> service) { 2 validateServiceInterface(service); 3 return (T) 4 Proxy.newProxyInstance( 5 service.getClassLoader(), 6 new Class<?>[] {service}, 7 new InvocationHandler() { 8 private final Platform platform = Platform.get(); 9 private final Object[] emptyArgs = new Object[0]; 10 11 @Override 12 public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) 13 throws Throwable { 14 // If the method is a method from Object then defer to normal invocation. 15 if (method.getDeclaringClass() == Object.class) { 16 return method.invoke(this, args); 17 } 18 args = args != null ? args : emptyArgs; 19 return platform.isDefaultMethod(method) 20 ? platform.invokeDefaultMethod(method, service, proxy, args) 21 : loadServiceMethod(method).invoke(args); 22 } 23 }); 24 }
InvocationHandler的invoke方法里传入了method, 这个method就是我们在service里定义的那些方法, 程序运行过程中会通过反射来获取
2, loadServiceMethod这里主要是用了cache, 如果map里有,就从map去拿, 否则就通过parseAnnotations()方法来获取一个ServiceMethod对象
1 ServiceMethod<?> loadServiceMethod(Method method) { 2 ServiceMethod<?> result = serviceMethodCache.get(method); 3 if (result != null) return result; 4 5 synchronized (serviceMethodCache) { 6 result = serviceMethodCache.get(method); 7 if (result == null) { 8 result = ServiceMethod.parseAnnotations(this, method); 9 serviceMethodCache.put(method, result); 10 } 11 } 12 return result; 13 }
点进去看看, 首先通过RequestFactory.parseAnnotations(retrofit, method)得到一个requestFactory对象, 然后HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory)
1 static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) { 2 RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); 3 4 Type returnType = method.getGenericReturnType(); 5 if (Utils.hasUnresolvableType(returnType)) { 6 throw methodError( 7 method, 8 "Method return type must not include a type variable or wildcard: %s", 9 returnType); 10 } 11 if (returnType == void.class) { 12 throw methodError(method, "Service methods cannot return void."); 13 } 14 15 return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); 16 }
RequestFactory.parseAnnotations(retrofit, method)这个方法主要是去解析我们在service里加的那些注解, 获取Http请求需要的一些信息,比如: header, body等等
1 static RequestFactory parseAnnotations(Retrofit retrofit, Method method) { 2 return new Builder(retrofit, method).build(); 3 }
1 RequestFactory build() { 2 for (Annotation annotation : methodAnnotations) { 3 parseMethodAnnotation(annotation); 4 }
1 private void parseMethodAnnotation(Annotation annotation) { 2 if (annotation instanceof DELETE) { 3 parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false); 4 } else if (annotation instanceof GET) { 5 parseHttpMethodAndPath("GET", ((GET) annotation).value(), false); 6 } else if (annotation instanceof HEAD) { 7 parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false); 8 } else if (annotation instanceof PATCH) { 9 parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true); 10 } else if (annotation instanceof POST) { 11 parseHttpMethodAndPath("POST", ((POST) annotation).value(), true); 12 } else if (annotation instanceof PUT) { 13 parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true); 14 } else if (annotation instanceof OPTIONS) { 15 parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false); 16 } else if (annotation instanceof HTTP) { 17 HTTP http = (HTTP) annotation; 18 parseHttpMethodAndPath(http.method(), http.path(), http.hasBody()); 19 } else if (annotation instanceof retrofit2.http.Headers) { 20 String[] headersToParse = ((retrofit2.http.Headers) annotation).value(); 21 if (headersToParse.length == 0) { 22 throw methodError(method, "@Headers annotation is empty."); 23 } 24 headers = parseHeaders(headersToParse); 25 } else if (annotation instanceof Multipart) { 26 if (isFormEncoded) { 27 throw methodError(method, "Only one encoding annotation is allowed."); 28 } 29 isMultipart = true; 30 } else if (annotation instanceof FormUrlEncoded) { 31 if (isMultipart) { 32 throw methodError(method, "Only one encoding annotation is allowed."); 33 } 34 isFormEncoded = true; 35 } 36 }
3, 接下来重点看看HttpServiceMethod类, 它里面实现了invoke()方法,
1 @Override 2 final @Nullable ReturnT invoke(Object[] args) { 3 Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter); 4 return adapt(call, args); 5 }
OkHttpCall 是 retrofit2.Call 的⼦类。上面的第一行代码负责将 ServiceMethod 解读到的信息(主要是⼀个 RequestFactory 、⼀个 OkHttpClient 和⼀个 ResponseConverter )封装进 OkHttpCall ; ⽽这个对象可以在需要的时候(例如它的 enqueue() ⽅法被调⽤的时候), 利⽤ RequestFactory 和 OkHttpClient 来创建⼀个 okhttp3.Call 对象,并调⽤这个 okhttp3.Call 对象来进⾏⽹络请求的发起,然后利⽤ ResponseConverter 对结果进⾏预处理之后,交回给 Retrofit 的 Callback
1 protected ReturnT adapt(Call<ResponseT> call, Object[] args) { 2 return callAdapter.adapt(call); 3 }
callAdapter一直往进跟, 发现这里就是我们从retrofit.Builder().addAdapterFactory(adapter)这里传进来的这个adapter
1 public CallAdapter<?, ?> nextCallAdapter( 2 @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { 3 Objects.requireNonNull(returnType, "returnType == null"); 4 Objects.requireNonNull(annotations, "annotations == null"); 5 6 int start = callAdapterFactories.indexOf(skipPast) + 1; 7 for (int i = start, count = callAdapterFactories.size(); i < count; i++) { 8 CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this); 9 if (adapter != null) { 10 return adapter; 11 } 12 }
adapt⽅法会使⽤⼀个 CallAdapter 对象来把 OkHttpCall 对象进⾏转换,⽣成⼀个新 的对象。
默认情况下,callAdapter返回的是⼀个 ExecutorCallbackCall ,它的作⽤是把操 作切回主线程后再交给 Callback 。 另外,如果有⾃定义的 CallAdapter,这⾥也可以⽣成别的类型的对象,例如 RxJava 的 Observable ,来让 Retrofit 可以和 RxJava 结合使⽤。
小结retrofit的关键实现:
1, 通过动态代理的方式为我们定义的接口生成一个实现类
2, 通过RequestFactory对我们接口中定义的注解进行解析,得到http请求需要的一些参数
3, 封装了okhttpCall去实现具体的网络请求
4, 通过convertFactory将请求返回的字节流转换成我们需要的格式,如json
5, 请求完成后,通过adapterFactory完成线程的切换, callAdapter默认返回的是⼀个 ExecutorCallbackCall ,它的作⽤是把操 作切回主线程, 我们也可以在创建retrofit时把它换成其他adapter, 比如RxJava的Observable