接着上一章继续分析上一章主要简单说了一下基本使用和注解,这一章,我们主要看源码,废话不多说了,直接上。先上一张图 从网络上拿来的
前面一章说了一下Retrofit的简单使用https://www.cnblogs.com/huangjialin/p/9492182.html
1 //创建retrofit 2 Retrofit retrofit = new Retrofit.Builder() 3 .baseUrl(url) //设置baseURl 4 .addConverterFactory(ScalarsConverterFactory.create()) //增加返回值为String的支持 5 .addConverterFactory(GsonConverterFactory.create()) 6 .build(); 7 ApiService apiService = retrofit.create(ApiService.class); 8 Call<SwitchTest> call = apiService.getInformation(); 9 call.enqueue(new Callback<SwitchTest>() { 10 @Override 11 public void onResponse(Call<SwitchTest> call, Response<SwitchTest> response) { 12 Log.d("huangjialin", "---onResponse----" + response.body().getMessage()); 13 } 14 15 @Override 16 public void onFailure(Call<SwitchTest> call, Throwable t) { 17 Log.d("huangjialin", "--- 失败----" ); 18 19 } 20 });
我们看一下new Retrofit.Builder()源码是怎么走的
1 public Builder() { 2 this(Platform.get()); 3 }
1 class Platform { 2 private static final Platform PLATFORM = findPlatform(); 3 4 static Platform get() { 5 return PLATFORM; 6 } 7 8 private static Platform findPlatform() { 9 try { 10 Class.forName("android.os.Build"); 11 if (Build.VERSION.SDK_INT != 0) { 12 return new Android(); 13 } 14 } catch (ClassNotFoundException ignored) { 15 } 16 try { 17 Class.forName("java.util.Optional"); 18 return new Java8(); 19 } catch (ClassNotFoundException ignored) { 20 } 21 return new Platform(); 22 } 23 //—————省略若干代码—————- 24 }
从代码中可以看出来,Builder后先是调用this(Platform.get());然后在调用findPlatform()方法,在findPlatform()方法中主要进行平台的判断,不同的平台返回不同的线程池。在最新的几个版本中去掉了iOS平台的判断。
好了,回过头来我们接着看build()方法是怎么执行的
1 public Retrofit build() { 2 if (baseUrl == null) { //从这里这里知道baseUrl一定不能为空,也就是说必须要设置,否则会抛异常 3 throw new IllegalStateException("Base URL required."); 4 } 5 6 okhttp3.Call.Factory callFactory = this.callFactory; //如果需要对OkHttpClient进行设置,则可以构建OkHttpClient对象,然后调用callFactory方法将设置好的OkHttpClient传进去。 7 if (callFactory == null) { 8 callFactory = new OkHttpClient(); 9 } 10 11 Executor callbackExecutor = this.callbackExecutor; 12 if (callbackExecutor == null) { 13 callbackExecutor = platform.defaultCallbackExecutor(); //将回调传递到主线程 14 } 15 16 // adapterFactories主要用于存储对Call进行转化的对象 17 List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories); 18 callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); 19 20 //主要用于存储数据转换后的对象 21 List<Converter.Factory> converterFactories = 22 new ArrayList<>(1 + this.converterFactories.size()); 23 24 // Add the built-in converter factory first. This prevents overriding its behavior but also 25 // ensures correct behavior when using converters that consume all types. 26 converterFactories.add(new BuiltInConverters()); 27 converterFactories.addAll(this.converterFactories); 28 29 //将retrofit对象返回来 30 return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), 31 unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly); 32 }
上面做的注释很清晰,也就是说build()后,我们可以拿到这个Retrofit这个对象,接着ApiService apiService = retrofit.create(ApiService.class);我们看看这句代码的源码是怎么走的
1 public <T> T create(final Class<T> service) { 2 //这里主要是进行一些判断验证,比如说我们这里定义的ApiService,这个只能定义为interfaces类型,而不能定义为class类型。并且interfaces不能被扩展 3 Utils.validateServiceInterface(service); 4 if (validateEagerly) { 5 eagerlyValidateMethods(service); 6 } 7 return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, 8 new InvocationHandler() { 9 private final Platform platform = Platform.get(); 10 11 @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args) 12 throws Throwable { 13 // 判断方法是不是属于对象的方法 14 if (method.getDeclaringClass() == Object.class) { 15 return method.invoke(this, args); 16 } 17 //判断是否在主线程 18 if (platform.isDefaultMethod(method)) { 19 return platform.invokeDefaultMethod(method, service, proxy, args); 20 } 21 ServiceMethod<Object, Object> serviceMethod = 22 (ServiceMethod<Object, Object>) loadServiceMethod(method); 23 OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); 24 return serviceMethod.adapt(okHttpCall); 25 } 26 }); 27 }
当进行一系列验证判断以后,Proxy.newProxyInstance来拿到一个动态代理,同时实现invoke()方法。通过当我们调用接口中的方法时,比如说调用登陆接口 Call<LoginModel> login(@Body Login login);,
这个时候就会调用InvocationHandler中的invoke方法,invoke()方法中有三个参数,第一个就是代理对象,第二个就是所调用的方法,比如说调用登陆接口,这个方法就是login,第三个就是方法参数了。
接着我们找到loadServiceMethod(method)我们看看是怎么执行的。
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 = new ServiceMethod.Builder<>(this, method).build(); 9 serviceMethodCache.put(method, result); 10 } 11 } 12 return result; 13 }
loadServiceMethod这个方法,首先进行一下判断,也就是说先从缓存中获取,看看缓存中有没有这个请求方法,如果有的话,那就直接返回,没有的话,通过new ServiceMethod.Builder<>(this, method).build();
来构建,然后在保存起来。我们看看build()中的源码
1 public ServiceMethod build() { 2 //调用了createCallAdapter方法,它最终会得到我们在构建Retrofit调用build方法时adapterFactories添加的对象的get方法 3 callAdapter = createCallAdapter(); 4 //获取到返回数据的类型 5 responseType = callAdapter.responseType(); 6 if (responseType == Response.class || responseType == okhttp3.Response.class) { 7 throw methodError("'" 8 + Utils.getRawType(responseType).getName() 9 + "' is not a valid response body type. Did you mean ResponseBody?"); 10 } 11 //这里面通过遍历来拿到我们适合的Converter的转化对象,由于retrofit可以调用addConverterFactory添加多个,如Gson 12 responseConverter = createResponseConverter(); 13 14 //这里主要是通过遍历拿到请求请求方法,如GET POST ,PUT这些 15 for (Annotation annotation : methodAnnotations) { 16 parseMethodAnnotation(annotation); 17 } 18 19 //这里主要进行一下判断,就是如果没有请求方法的话,就会抛出异常 20 if (httpMethod == null) { 21 throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.)."); 22 } 23 24 if (!hasBody) { 25 if (isMultipart) { 26 throw methodError( 27 "Multipart can only be specified on HTTP methods with request body (e.g., @POST)."); 28 } 29 if (isFormEncoded) { 30 throw methodError("FormUrlEncoded can only be specified on HTTP methods with " 31 + "request body (e.g., @POST)."); 32 } 33 } 34 35 int parameterCount = parameterAnnotationsArray.length; 36 parameterHandlers = new ParameterHandler<?>[parameterCount]; 37 for (int p = 0; p < parameterCount; p++) { 38 Type parameterType = parameterTypes[p]; 39 if (Utils.hasUnresolvableType(parameterType)) { 40 throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s", 41 parameterType); 42 } 43 44 //这里获取到我们接口上面的参数注解比如说@Query @QueryMap这些 45 Annotation[] parameterAnnotations = parameterAnnotationsArray[p]; 46 if (parameterAnnotations == null) { 47 throw parameterError(p, "No Retrofit annotation found."); 48 } 49 50 parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations); 51 } 52 53 if (relativeUrl == null && !gotUrl) { 54 throw methodError("Missing either @%s URL or @Url parameter.", httpMethod); 55 } 56 if (!isFormEncoded && !isMultipart && !hasBody && gotBody) { 57 throw methodError("Non-body HTTP method cannot contain @Body."); 58 } 59 if (isFormEncoded && !gotField) { 60 throw methodError("Form-encoded method must contain at least one @Field."); 61 } 62 if (isMultipart && !gotPart) { 63 throw methodError("Multipart method must contain at least one @Part."); 64 } 65 66 //返回ServiceMethod对象 67 return new ServiceMethod<>(this); 68 }
上面这个方法主要目的就是为了拿到ServiceMethod对象。回过头来,我们继续看retrofit的create()方法
1 ServiceMethod<Object, Object> serviceMethod = 2 (ServiceMethod<Object, Object>) loadServiceMethod(method); 3 OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
当拿到serviceMethod对象以后,接着就执行new OkHttpCall();来得到okHttpCall,并且最后返回serviceMethod.adapt(okHttpCall),我们进入OkHttpCall()对象看看
1 final class OkHttpCall<T> implements Call<T> { 2 3 //------省略若干代码-------- 4 5 @Override public synchronized Request request() { 6 okhttp3.Call call = rawCall; 7 if (call != null) { 8 return call.request(); 9 } 10 if (creationFailure != null) { 11 if (creationFailure instanceof IOException) { 12 throw new RuntimeException("Unable to create request.", creationFailure); 13 } else if (creationFailure instanceof RuntimeException) { 14 throw (RuntimeException) creationFailure; 15 } else { 16 throw (Error) creationFailure; 17 } 18 } 19 try { 20 return (rawCall = createRawCall()).request(); 21 } catch (RuntimeException | Error e) { 22 throwIfFatal(e); // Do not assign a fatal error to creationFailure. 23 creationFailure = e; 24 throw e; 25 } catch (IOException e) { 26 creationFailure = e; 27 throw new RuntimeException("Unable to create request.", e); 28 } 29 } 30 31 @Override public void enqueue(final Callback<T> callback) { 32 checkNotNull(callback, "callback == null"); 33 34 okhttp3.Call call; 35 Throwable failure; 36 37 synchronized (this) { 38 if (executed) throw new IllegalStateException("Already executed."); 39 executed = true; 40 41 call = rawCall; 42 failure = creationFailure; 43 if (call == null && failure == null) { 44 try { 45 call = rawCall = createRawCall(); 46 } catch (Throwable t) { 47 throwIfFatal(t); 48 failure = creationFailure = t; 49 } 50 } 51 } 52 53 if (failure != null) { 54 callback.onFailure(this, failure); 55 return; 56 } 57 58 if (canceled) { 59 call.cancel(); 60 } 61 62 call.enqueue(new okhttp3.Callback() { 63 @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) { 64 Response<T> response; 65 try { 66 response = parseResponse(rawResponse); 67 } catch (Throwable e) { 68 callFailure(e); 69 return; 70 } 71 72 try { 73 callback.onResponse(OkHttpCall.this, response); 74 } catch (Throwable t) { 75 t.printStackTrace(); 76 } 77 } 78 79 @Override public void onFailure(okhttp3.Call call, IOException e) { 80 callFailure(e); 81 } 82 83 private void callFailure(Throwable e) { 84 try { 85 callback.onFailure(OkHttpCall.this, e); 86 } catch (Throwable t) { 87 t.printStackTrace(); 88 } 89 } 90 }); 91 } 92 93 // --------省略若干代码---------
到这里,基本很明了,看过我前面的okhttp源码解析的朋友,这里就会觉得很熟悉了,这里通过实现 Call接口,然后通过request()和enqueue()这两个方法,然后将请求的结果回调回来,从而实现网络通信。
当然,这里只是retrofit一些基本的流程在源码中是这样走的,如果说要非常非常详细的源码,这不是一两篇文章能写完的,光retrofit就可以写出一本书了,当然,目前的水平,还没有达到那个地步,慢慢来。