![]() |
果断的可乐 · 金融风险的防范与法律制度的完善· 5 月前 · |
![]() |
千杯不醉的黄瓜 · 2022年上海大学优秀博士学位论文评选结果公 ...· 12 月前 · |
![]() |
想旅行的小笼包 · 宠物捕捉大师,神雕秘传 ...· 1 年前 · |
![]() |
气宇轩昂的豆腐 · 如何使用awk或sed在文件中的每个单词的末 ...· 1 年前 · |
目前的网络框架基本上都是使用Retrofit+okhttp一起进行使用,那么我们来看看retrofit究竟做了些什么。
结合上一篇的OkHttp源码解析,在这个的基础上加上了Retrofit,下面是正常使用时候的代码。
private void initRetrofit() { OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new TokenHeaderInterceptor()) // 动态添加token .addInterceptor(new NullResponseInterceptor()) // 返回空字符的时候显示 .connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS) .writeTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS) .readTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS) .build(); // JSON 问题的解析处理 Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 Gson gson = new GsonBuilder().setLenient().create(); retrofit = new Retrofit.Builder() // 使用建造者模式 .baseUrl(Constant.HTTP_URL) // 请求host .client(client) // okhttp实例对象 .addConverterFactory(WGsonConverterFactory.create(gson)) // 添加 转换器工厂 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 请求指定适配器 RxJava .build();
上面的代码是对Retrofit进行一个初始化的操作。
Retrofit # Builder()
Builder(Platform platform) { // 将平台信息赋值给成员变量platform this.platform = platform; public Builder() { // 获取平台相关信息 this(Platform.get());
Platform # get()
private static final Platform PLATFORM = findPlatform(); static Platform get() { return PLATFORM; private static Platform findPlatform() { try { Class.forName("android.os.Build"); if (Build.VERSION.SDK_INT != 0) { // 如果是Android平台就创建实例Android() return new Android(); } catch (ClassNotFoundException ignored) { try { Class.forName("java.util.Optional"); return new Java8(); } catch (ClassNotFoundException ignored) { return new Platform();
Android是Platform里面的一个静态内部类。
Platform # Android
static class Android extends Platform { @IgnoreJRERequirement // Guarded by API check. @Override boolean isDefaultMethod(Method method) { if (Build.VERSION.SDK_INT < 24) { // 小于7.0 return false; return method.isDefault(); @Override public Executor defaultCallbackExecutor() { return new MainThreadExecutor(); // 实例化一个在主线程执行的线程 @Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories( @Nullable Executor callbackExecutor) { if (callbackExecutor == null) throw new AssertionError(); ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor); return Build.VERSION.SDK_INT >= 24 ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory) // 完成请求返回适配器工厂,执行请求工厂 : singletonList(executorFactory); // 只有一个执行请求工厂 @Override int defaultCallAdapterFactoriesSize() { // 默认请求适配器工厂数量 return Build.VERSION.SDK_INT >= 24 ? 2 : 1; // 大于7.0 2个 其他 1个 @Override List<? extends Converter.Factory> defaultConverterFactories() { // 默认转换器工厂 return Build.VERSION.SDK_INT >= 24 ? singletonList(OptionalConverterFactory.INSTANCE) : Collections.<Converter.Factory>emptyList(); @Override int defaultConverterFactoriesSize( ) { // 默认转换器数量 return Build.VERSION.SDK_INT >= 24 ? 1 : 0; // 在主线程中进行执行的线程,使用Handler进行线程切换。 static class MainThreadExecutor implements Executor { private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable r) { handler.post(r);
.baseUrl(Constant.HTTP_URL)
public Builder baseUrl(String baseUrl) { checkNotNull(baseUrl, "baseUrl == null"); // 对其判空处理 空 抛出异常 return baseUrl(HttpUrl.get(baseUrl));
HttpUrl.get(baseUrl)
public static HttpUrl get(String url) { return new Builder().parse(null, url).build(); // 建造者模式
new Builder().parse(null, url)
Builder parse(@Nullable HttpUrl base, String input) { // 如果前面或者后面有 \t \r \n \f 空格 进行处理 int pos = skipLeadingAsciiWhitespace(input, 0, input.length()); // 获取input前面有效字符所在的index值 int limit = skipTrailingAsciiWhitespace(input, pos, input.length()); // 获取input后面有效字符所在的index值 // Scheme. 返回输入中在scheme字符之后的“:”索引。如果输入没有从pos开始的方案,则返回-1。 // inputs长度小于2,input的pos位置不为a-z或者A-Z的字符直接返回-1 int schemeDelimiterOffset = schemeDelimiterOffset(input, pos, limit); // 拿到scheme所在位置的index值 if (schemeDelimiterOffset != -1) { if (input.regionMatches(true, pos, "https:", 0, 6)) { // 获取input请求是否是https请求 this.scheme = "https"; pos += "https:".length(); // 确定请求方式https pos开始向右走 } else if (input.regionMatches(true, pos, "http:", 0, 5)) { // 获取input请求是否是http请求 this.scheme = "http"; pos += "http:".length(); // 确定请求方式http pos开始向右走 } else { // 如果是其他类型 抛出异常 throw new IllegalArgumentException("Expected URL scheme 'http' or 'https' but was '" + input.substring(0, schemeDelimiterOffset) + "'"); } else if (base != null) { // 由上面的代码可以知道这里的base是null this.scheme = base.scheme; } else { // 其他情况 抛出异常 throw new IllegalArgumentException( "Expected URL scheme 'http' or 'https' but no colon was found"); // Authority. boolean hasUsername = false; boolean hasPassword = false; // 如果 input = "https://www.baidu.com" // 前面已经确定了https: 下面的方法确定了 https:// pos+=2 int slashCount = slashCount(input, pos, limit); // 进行跳过双斜杠 或者反义符斜杆 得到// 的数量 这里是 2 if (slashCount >= 2 || base == null || !base.scheme.equals(this.scheme)) { pos += slashCount; authority: while (true) { // 从pos开始到limit位置都不包含这些字符就返回limit www.baidu.com 不包含 返回limit int componentDelimiterOffset = delimiterOffset(input, pos, limit, "@/\\?#"); int c = componentDelimiterOffset != limit ? input.charAt(componentDelimiterOffset) : -1; // 执行这个 switch (c) { // c = -1 case '@': // @情况特殊 // User info precedes. if (!hasPassword) { // 由上面代码可知 这里是false值 int passwordColonOffset = delimiterOffset( input, pos, componentDelimiterOffset, ':'); // 判断剩余字符中是否含有:字符 并返回下标值 // 通过以下转换返回[pos..limit]范围内输入的子字符串:跳过制表符、换行符、换行符和回车符。在查询中,“”被编码为“+”,而“+”被编码为“%2B”。 // encodeSet中的字符是百分比编码的。控制字符和非ASCII字符采用百分比编码。所有其他字符都被复制而不进行转换。 String canonicalUsername = canonicalize( input, pos, passwordColonOffset, USERNAME_ENCODE_SET, true, false, false, true, null); this.encodedUsername = hasUsername ? this.encodedUsername + "%40" + canonicalUsername : canonicalUsername; // 拿到编码用户名 if (passwordColonOffset != componentDelimiterOffset) { hasPassword = true; this.encodedPassword = canonicalize(input, passwordColonOffset + 1, componentDelimiterOffset, PASSWORD_ENCODE_SET, true, false, false, true, null); // 拿到编码密码 hasUsername = true; } else { this.encodedPassword = this.encodedPassword + "%40" + canonicalize(input, pos, componentDelimiterOffset, PASSWORD_ENCODE_SET, true, false, false, true, null); // 拿到编码密码 pos = componentDelimiterOffset + 1; break; case -1: case '/': case '\\': case '?': case '#': // 根据上面分析 componentDelimiterOffset = limit 查找输入中的第一个“:”,在大括号“[…]”之间跳过字符 int portColonOffset = portColonOffset(input, pos, componentDelimiterOffset); // 返回也是limit if (portColonOffset + 1 < componentDelimiterOffset) { // 条件不满足 如果字符中含有接口 即满足条件 例如 127.0.0.1:8080 host = canonicalizeHost(input, pos, portColonOffset); // 如果www.baidu.com含有%转为utf-8字符 如果包含[]则需要去除字符 port = parsePort(input, portColonOffset + 1, componentDelimiterOffset); // 解析端口号 如果在 0 - 65535之间则返回,否则返回-1 if (port == -1) { // 端口号不对抛出异常 throw new IllegalArgumentException("Invalid URL port: \"" + input.substring(portColonOffset + 1, componentDelimiterOffset) + '"'); } else { host = canonicalizeHost(input, pos, portColonOffset); // 解析host port = defaultPort(scheme); // 解析端口号 if (host == null) { throw new IllegalArgumentException( INVALID_HOST + ": \"" + input.substring(pos, portColonOffset) + '"'); pos = componentDelimiterOffset; break authority; } else { // This is a relative link. Copy over all authority components. Also maybe the path & query. this.encodedUsername = base.encodedUsername(); this.encodedPassword = base.encodedPassword(); this.host = base.host; this.port = base.port; this.encodedPathSegments.clear(); this.encodedPathSegments.addAll(base.encodedPathSegments()); if (pos == limit || input.charAt(pos) == '#') { encodedQuery(base.encodedQuery()); // Resolve the relative path. int pathDelimiterOffset = delimiterOffset(input, pos, limit, "?#"); // pos-limit字段是否含有?# 获取最近的一个下标值 resolvePath(input, pos, pathDelimiterOffset); // 会在最后一个encodedPathSegments集合中设置为“”空字符串 pos = pathDelimiterOffset; // Query. if (pos < limit && input.charAt(pos) == '?') { // 有参数的情况 int queryDelimiterOffset = delimiterOffset(input, pos, limit, '#'); this.encodedQueryNamesAndValues = queryStringToNamesAndValues(canonicalize( // 获取参数名称和值value input, pos + 1, queryDelimiterOffset, QUERY_ENCODE_SET, true, false, true, true, null)); pos = queryDelimiterOffset; // Fragment. if (pos < limit && input.charAt(pos) == '#') { // 锚点位置解析 this.encodedFragment = canonicalize( input, pos + 1, limit, FRAGMENT_ENCODE_SET, true, false, false, false, null); return this;
HttpUrl # Builder # build()
public HttpUrl build() { if (scheme == null) throw new IllegalStateException("scheme == null"); if (host == null) throw new IllegalStateException("host == null"); return new HttpUrl( this); // 使用上面所有的参数创建一个httpUrl实例对象 这里的this为Builder
HttpUrl(this) 这里的this指Builder
HttpUrl(Builder builder) { // 对build之前设置的数据进行初始化赋值 this.scheme = builder.scheme; this.username = percentDecode(builder.encodedUsername, false); // % 字符编码utf-8处理 this.password = percentDecode(builder.encodedPassword, false); this.host = builder.host; this.port = builder.effectivePort(); this.pathSegments = percentDecode(builder.encodedPathSegments, false); this.queryNamesAndValues = builder.encodedQueryNamesAndValues != null ? percentDecode(builder.encodedQueryNamesAndValues, true) : null; this.fragment = builder.encodedFragment != null ? percentDecode(builder.encodedFragment, false) : null; this.url = builder.toString();
baseUrl(HttpUrl.get(baseUrl))
public Builder baseUrl(HttpUrl baseUrl) { checkNotNull(baseUrl, "baseUrl == null"); // 判空处理 List<String> pathSegments = baseUrl.pathSegments(); // 获取 pathSegments if (!"".equals(pathSegments.get(pathSegments.size() - 1))) { // 默认为“” throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl); this.baseUrl = baseUrl; return this;
.client(client)
public Builder client(OkHttpClient client) { // 设置 callFactory return callFactory(checkNotNull(client, "client == null")); // 判空
.addConverterFactory(WGsonConverterFactory.create(gson)) 设置转换器工厂
public Builder addConverterFactory(Converter.Factory factory) { converterFactories.add(checkNotNull(factory, "factory == null")); // 直接将转换器工厂添加到转换器工厂集合中 return this;
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
public Builder addCallAdapterFactory(CallAdapter.Factory factory) { callAdapterFactories.add(checkNotNull(factory, "factory == null")); // 添加到请求适配器工厂集合中 return this;
new Retrofit.Builder().build(); 开始创建Retrofit实例`
public Retrofit build() { if (baseUrl == null) { throw new IllegalStateException("Base URL required."); okhttp3.Call.Factory callFactory = this.callFactory; // client 不为null if (callFactory == null) { callFactory = new OkHttpClient(); Executor callbackExecutor = this.callbackExecutor; // 请求返回执行线程 if (callbackExecutor == null) { callbackExecutor = platform.defaultCallbackExecutor(); // Android平台默认是通过Handler在主线程中进行执行 // Make a defensive copy of the adapters and add the default Call adapter. List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories); callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor)); // Make a defensive copy of the converters. defaultConverterFactoriesSize大于等于7.0 size为1 否则为0 List<Converter.Factory> converterFactories = new ArrayList<>( 1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize()); // 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()); converterFactories.addAll(this.converterFactories); converterFactories.addAll(platform.defaultConverterFactories()); // 默认的转换器工厂 // Retrofit对象的实例化 return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories), unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
参数赋值,进行实例化Retrofit对象。
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl, List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories, @Nullable Executor callbackExecutor, boolean validateEagerly) { this.callFactory = callFactory; this.baseUrl = baseUrl; this.converterFactories = converterFactories; // Copy+unmodifiable at call site. this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site. this.callbackExecutor = callbackExecutor; this.validateEagerly = validateEagerly;
2. 调用
public interface InterfaceApi { // 接口类 * 根据用户id更新用户信息 * @return @POST("/api/watch/account/update/{id}") Observable<BaseJson<ResponseUserInfoBean>> updateUserInfoUseId(@Path("id") long userId, @Body RequestBody json);
代码调用请求接口
RetrofitManager.getInstance().requestData(InterfaceApi.class) .updateUserInfoUseId(userId,RequestBodyUtils.getRequestBody(new Gson().toJson(bean))) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver<BaseJson<ResponseUserInfoBean>>() { @Override public void startAnalysis() {} @Override public void getData(BaseJson<ResponseUserInfoBean> data) { mUpdateUserInfo.setValue(data.getData()); @Override public void onErrorInfo(Throwable e) { mUpdateUserInfo.setValue(null); mView.showToast(e.getMessage()); });
请求数据会进行调用这个方法,retrofit调用了create
public <T> T requestData(Class<T> tClass){ return retrofit.create(tClass);
retrofit.create(tClass);
public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service); // 判断service的类对象是否是接口类型 并且没有派生自其它接口类 if (validateEagerly) { // 上面代码未进行设置 默认为 false eagerlyValidateMethods(service); // service.getClassLoader() 拿取当前接口执行类的类加载器 PathClassLoader // 代理对象 service 接口类 // 动态代理模式执行数据的请求 return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { private final Platform platform = Platform.get(); private final Object[] emptyArgs = new Object[0]; // 代理对象是service的远程代理 method 是当前service执行的方法名 args是当前方法执行的所有参数集合 @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. // method.getDeclaringClass() 当前方法所属的类class 目前我这里是接口类InterfaceApi.class 不是Object.class if (method.getDeclaringClass() == Object.class) { // 所以不会通过这个方法 return method.invoke(this, args); // 按照正常调用执行方法 if (platform.isDefaultMethod(method)) { // 是否是默认方法 是的情况 正常调用 Java8特性 可以不管 return platform.invokeDefaultMethod(method, service, proxy, args); return loadServiceMethod(method).invoke(args != null ? args : emptyArgs); });
eagerlyValidateMethods(service);
private void eagerlyValidateMethods(Class<?> service) { Platform platform = Platform.get(); // 拿取到Android平台对象 for (Method method : service.getDeclaredMethods()) { // 获取service接口内所有private修饰的方法 if (!platform.isDefaultMethod(method)) { // 判断 非Android平台默认的方法 则执行下面操作 loadServiceMethod(method);
loadServiceMethod(method);
ServiceMethod<?> loadServiceMethod(Method method) { ServiceMethod<?> result = serviceMethodCache.get(method); // 从集合中去获取这个方法 if (result != null) return result; // 如果已经存在,则返回 synchronized (serviceMethodCache) { // Map集合中不存在 加锁进行处理 ,保证方法的唯一性 result = serviceMethodCache.get(method); // 再一次进行获取 if (result == null) { // 当前方法依旧不存在 result = ServiceMethod.parseAnnotations(this, method); // 解析当前方法 serviceMethodCache.put(method, result); // 将当前解析之后的方法放入到集合中 return result;
ServiceMethod属于抽象类,只有两个方法 parseAnnotations 和 invoke
abstract class ServiceMethod<T> { static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) { // 对当前方法的所有信息进行解析 方法上的注解 方法参数注解 方法参数值等一系列的解析 RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); Type returnType = method.getGenericReturnType(); // 获取当前方法返回类型类 if (Utils.hasUnresolvableType(returnType)) { // 判断返回类型是否是T 或者 通配符类型 throw methodError(method, "Method return type must not include a type variable or wildcard: %s", returnType); if (returnType == void.class) { // 返回类型为 空 throw methodError(method, "Service methods cannot return void."); // 实例化HttpServiceMethod对象 return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); abstract T invoke(Object[] args);
RequestFactory.parseAnnotations(retrofit, method);
final class RequestFactory { static RequestFactory parseAnnotations(Retrofit retrofit, Method method) { return new Builder(retrofit, method).build(); // 建造者模式
new Builder(retrofit, method);
Builder(Retrofit retrofit, Method method) { this.retrofit = retrofit; // retrofit实例 this.method = method; // 当前调用方法 this.methodAnnotations = method.getAnnotations(); // 获取当前方法注解集合 eg:@POST // 获取当前方法传入参数类型集合 eg (String url) String.class // 如果当前数据传入的参数有泛型类型的参数 这个方法可以返回泛型的完整信息 eg:(List<String> list) java.util.List<java.lang.String> // getParameterTypes(); 这个方法仅返回泛型信息 eg:(List<String> list) java.util.List this.parameterTypes = method.getGenericParameterTypes(); // 获取当前方法传入参数的注解集合 eg (@Query("name") String name) this.parameterAnnotationsArray = method.getParameterAnnotations();
new Builder(retrofit, method).build()方法
RequestFactory build() { for (Annotation annotation : methodAnnotations) { // 遍历作用方法上面的注解集合 parseMethodAnnotation(annotation); // 进行解析 if (httpMethod == null) { // 请求方式注解是否为null throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.)."); if (!hasBody) { // 是否有请求体 parseMethodAnnotation 由这个方法体现 DELETE GET OPTIONS HEAD 为false if (isMultipart) { // 没有请求体但是是表单提交(带有文件) throw methodError(method, "Multipart can only be specified on HTTP methods with request body (e.g., @POST)."); if (isFormEncoded) { // 是否是表单提交 throw methodError(method, "FormUrlEncoded can only be specified on HTTP methods with " + "request body (e.g., @POST)." ); int parameterCount = parameterAnnotationsArray.length; // 参数注解长度 parameterHandlers = new ParameterHandler<?>[parameterCount]; // 创建ParameterHandler集合对象 for (int p = 0; p < parameterCount; p++) { // 对参数注解进行逐一解析 parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]); if (relativeUrl == null && !gotUrl) { throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod); if (!isFormEncoded && !isMultipart && !hasBody && gotBody) { throw methodError(method, "Non-body HTTP method cannot contain @Body."); if (isFormEncoded && !gotField) { throw methodError(method, "Form-encoded method must contain at least one @Field."); if (isMultipart && !gotPart) { throw methodError(method, "Multipart method must contain at least one @Part."); return new RequestFactory(this); // 实例化请求工厂对象
parseMethodAnnotation(annotation); 作用于方法上面的注解进行解析
private void parseMethodAnnotation(Annotation annotation) { if (annotation instanceof DELETE) { parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false); // hasBody给的false } else if (annotation instanceof GET) { parseHttpMethodAndPath("GET", ((GET) annotation).value(), false); // hasBody给的false } else if (annotation instanceof HEAD) { parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false); // hasBody给的false } else if (annotation instanceof PATCH) { parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true); // hasBody给的true } else if (annotation instanceof POST) { parseHttpMethodAndPath("POST", ((POST) annotation).value(), true); // hasBody给的true } else if (annotation instanceof PUT) { parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true); // hasBody给的true } else if (annotation instanceof OPTIONS) { parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false); // hasBody给的false } else if (annotation instanceof HTTP) { HTTP http = (HTTP) annotation; // 如果注解为@HTTP,即传入http相关信息进行解析 parseHttpMethodAndPath(http.method(), http.path(), http.hasBody()); // hasBody默认为false 实际值需要看注解中给的是什么 } else if (annotation instanceof retrofit2.http.Headers) { // 如果添加了Headers请求头集合 String[] headersToParse = ((retrofit2.http.Headers) annotation).value(); if (headersToParse.length == 0) { // 获取集合为null 抛出异常 throw methodError(method, "@Headers annotation is empty."); headers = parseHeaders(headersToParse); // 解析请求头相关信息 } else if (annotation instanceof Multipart) { // 表单提交(含有文件)类型 if (isFormEncoded) { // 表单提交只能使用一个类型 throw methodError(method, "Only one encoding annotation is allowed."); isMultipart = true; } else if (annotation instanceof FormUrlEncoded) { // 表单提交 if (isMultipart) { // 表单提交只能使用一个类型 throw methodError(method, "Only one encoding annotation is allowed." ); isFormEncoded = true;
parseHttpMethodAndPath(“DELETE”, ((DELETE) annotation).value(), false); 等 一系列方法解析
private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) { if (this.httpMethod != null) { throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.", this.httpMethod, httpMethod); this.httpMethod = httpMethod; this.hasBody = hasBody; if (value.isEmpty()) { // 内容为空 则返回 return; // Get the relative URL path and existing query string, if present. int question = value.indexOf('?'); // 判断value中是否存在?字符 if (question != -1 && question < value.length() - 1) { // !=-1 表示value中有 // Ensure the query string does not have any named parameters. // eg: app/watch/list?userid=123456 下面代码拿取数据得到 userid=123456 String queryParams = value.substring(question + 1); // PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}"); // queryParams是否有进行匹配的字符 eg userid={$userid} Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams); if (queryParamMatcher.find()) { // 如果存在 即抛出异常,这个需要使用@Query注解写到参数中 throw methodError(method, "URL query string \"%s\" must not have replace block. " + "For dynamic query parameters use @Query.", queryParams); this.relativeUrl = value; this.relativeUrlParamNames = parsePathParameters(value); // 解析方法中路径字符,并将符合条件的String字符进行返回
parsePathParameters(value);
static Set<String> parsePathParameters(String path) { // PARAM_URL_REGEX = Pattern.compile("\\{(" + PARAM + ")\\}"); // path是否有进行匹配的字符 eg /api/watch/account/update/{id} Matcher m = PARAM_URL_REGEX.matcher(path); Set<String> patterns = new LinkedHashSet<>(); while (m.find()) { // 得到匹配是有的, patterns.add(m.group(1)); // 将匹配到的字符串添加到Set集合中, Set集合特点,不能重复 return patterns;
如果是HTTP注解
@Documented @Target(METHOD) @Retention(RUNTIME) public @interface HTTP { String method(); * A relative or absolute path, or full URL of the endpoint. This value is optional if the first * parameter of the method is annotated with {@link Url @Url}. * See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how * this is resolved against a base URL to create the full endpoint URL. String path() default ""; boolean hasBody() default false; // 默认的hasBody 为false
parseHeaders(headersToParse);
例如下面代码中的添加headers请求头信息
public interface UserService { @Headers({ "Accept: application/vnd.yourapi.v1.full+json", "User-Agent: Your-App-Name" @GET("/app/{userid}") Call<UserInfo> getUserInfo(@Path("userid") long userid);
private Headers parseHeaders(String[] headers) { Headers.Builder builder = new Headers.Builder(); for (String header : headers) { // 遍历所有的header int colon = header.indexOf(':'); // 获取当前header中:字符所在的下标值 if (colon == -1 || colon == 0 || colon == header.length() - 1) { // 出现这些情况表示没有出现:字符 抛出异常 throw methodError(method, "@Headers value must be in the form \"Name: Value\". Found: \"%s\"", header); String headerName = header.substring(0, colon); // 请求头名称 String headerValue = header.substring(colon + 1).trim(); // 请求头的内容 if ("Content-Type".equalsIgnoreCase(headerName)) { // 如果请求头为Content-Type需要进行特殊处理 try { contentType = MediaType.get(headerValue); // 请求类型的设置 } catch (IllegalArgumentException e) { throw methodError(method, e, "Malformed content type: %s", headerValue); } else { builder.add (headerName, headerValue); // 主要添加到namesAndValues集合中 return builder.build();
builder.build();
public Headers build() { return new Headers(this); // 实例化了一个Header对象
将builder中得到的namesAndValues集合赋值给Header的成员变量
Headers(Builder builder) { this.namesAndValues = builder.namesAndValues.toArray(new String[builder.namesAndValues.size()]);
上面的代码是对作用于方法上的注解进行解析的,下面我们来看一下作用于方法参数的注解进行解析。
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
// p 当前方法的参数下标 // parameterType 当前方法的参数类型 // annotations 当前方法的参数注解 private ParameterHandler<?> parseParameter( int p, Type parameterType, @Nullable Annotation[] annotations) { ParameterHandler<?> result = null; if (annotations != null) { for (Annotation annotation : annotations) { ParameterHandler<?> annotationAction = parseParameterAnnotation(p, parameterType, annotations, annotation); if (annotationAction == null) { continue; if (result != null) { // 出现多个Retrofit的注解,只能使用一个 throw parameterError(method, p, "Multiple Retrofit annotations found, only one allowed."); result = annotationAction; if (result == null) { // 没有找到Retrofit相对应的注解 throw parameterError(method, p, "No Retrofit annotation found."); return result;
parseParameterAnnotation(p, parameterType, annotations, annotation); 开始解析
下面的代码有点长
@Nullable private ParameterHandler<?> parseParameterAnnotation( int p, Type type, Annotation[] annotations, Annotation annotation) { if (annotation instanceof Url) { validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 if (gotUrl) { // 如果出现两次@Url注解 抛出异常 throw parameterError(method, p, "Multiple @Url method annotations found."); if (gotPath) { // @Path 与 @Url 不能同时使用 否则抛出异常 throw parameterError(method, p, "@Path parameters may not be used with @Url."); if (gotQuery) { // @Url参数不能出现在@Query之后。 throw parameterError(method, p, "A @Url parameter must not come after a @Query."); if (gotQueryName) { // @Url参数不能出现在@QueryName之后。 throw parameterError(method, p, "A @Url parameter must not come after a @QueryName."); if (gotQueryMap) { // @Url参数不能出现在@QueryMap之后。 throw parameterError(method, p, "A @Url parameter must not come after a @QueryMap."); if (relativeUrl != null) { // @Url 不能与httpMethod里面注解一起使用 具体见下面判断代码 throw parameterError(method, p, "@Url cannot be used with @%s URL", httpMethod); gotUrl = true; // 获取Url成功 if (type == HttpUrl.class || type == String.class || type == URI.class || (type instanceof Class && "android.net.Uri".equals(((Class<?>) type).getName()))) { return new ParameterHandler.RelativeUrl(); // 对relativeUrl赋值处理 } else { throw parameterError(method, p, "@Url must be okhttp3.HttpUrl, String, java.net.URI, or android.net.Uri type."); } else if (annotation instanceof Path) { validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 if (gotQuery) { // @Path必须在@Query注解之前使用 throw parameterError(method, p, "A @Path parameter must not come after a @Query."); if (gotQueryName) { // @Path必须在@QueryName注解之前使用 throw parameterError(method, p, "A @Path parameter must not come after a @QueryName."); if (gotQueryMap) { // @Path必须在@QueryMap注解之前使用 throw parameterError(method, p, "A @Path parameter must not come after a @QueryMap." ); if (gotUrl) { // @Path不能与@Url同时使用 throw parameterError(method, p, "@Path parameters may not be used with @Url."); if (relativeUrl == null) { // @Path必须在与类型是HttpUrl/String/Uri/android.net.Uri一起使用 throw parameterError(method, p, "@Path can only be used with relative url on @%s", httpMethod); gotPath = true; // 获取到Path成功 Path path = (Path) annotation; // path的注解 String name = path.value(); // path注解的value值 validatePathName(p, name);// 对注解和value进行验证 查看relativeUrlParamNames是否包含当前注解信息 如果没有就抛出异常 Converter<?, String> converter = retrofit.stringConverter(type, annotations); // 将转换器工厂替换成String // 注解的value值 转换器String 路径编码(未设置默认为false) return new ParameterHandler.Path<>(name, converter, path.encoded()); // 创建path对象 } else if (annotation instanceof Query) { // 当前参数注解类型为 @Query validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 Query query = (Query) annotation; String name = query.value(); boolean encoded = query.encoded(); Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 gotQuery = true; // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (Iterable.class.isAssignableFrom(rawParameterType)) { // eg : List、Collection等 返回true if (!(type instanceof ParameterizedType)) { // type 类型不是参数化类型 抛出异常 参数异常 throw parameterError(method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + "<String>)"); ParameterizedType parameterizedType = (ParameterizedType) type; // 如果内部是属于通配符类型 获取通配符表达式对象的泛型限定的上边界的类型 List<? extends Number> 获取 Number Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); Converter<?, String> converter = retrofit.stringConverter(iterableType, annotations); // 将转换器工厂替换成String return new ParameterHandler.Query<>(name, converter, encoded).iterable(); // 创建参数Query实例 } else if (rawParameterType.isArray()) { // [] 数组类型 Array.newInstance().getClass(); 进行返回 的处理 // 如果是基础类型的数组类型 则返回基础类型的class对象 例如 if (boolean.class == type) return Boolean.class; 其他情况直接返回type Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); Converter<?, String> converter = retrofit.stringConverter(arrayComponentType, annotations); // 将转换器工厂替换成String return new ParameterHandler.Query<>(name, converter, encoded).array(); // 创建参数Query实例 } else { // 其他情况 直接Class对象 或者 类型变量 String T 等 Converter<?, String> converter = retrofit.stringConverter(type, annotations); // 将转换器工厂替换成String return new ParameterHandler.Query<>(name, converter, encoded); // 创建参数Query实例 } else if (annotation instanceof QueryName) { // 当前参数类型注解为 @QueryName validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 QueryName query = (QueryName) annotation; boolean encoded = query.encoded(); Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 gotQueryName = true; // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (Iterable.class.isAssignableFrom(rawParameterType)) { // 集合类型 if (!(type instanceof ParameterizedType)) { // type 类型不是参数化类型 抛出参数化异常 throw parameterError(method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + "<String>)"); ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); // 拿到实际数据类型 通配符类型向上取对象 Converter<?, String> converter = retrofit.stringConverter(iterableType, annotations); // 将转换器工厂替换成String return new ParameterHandler.QueryName<>(converter, encoded).iterable(); // 实例化QueryName对象 } else if (rawParameterType.isArray()) { // 数组类型 Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); // 八大基础类型则返回基础类型对应对象class 其他直接返回传入类型 Converter<?, String> converter = retrofit.stringConverter(arrayComponentType, annotations); // 将转换器工厂替换成String return new ParameterHandler.QueryName<>(converter, encoded).array(); // 实例化QueryName对象 } else { // 其他情况 Converter<?, String> converter = retrofit.stringConverter(type, annotations); // 将转换器工厂替换成String return new ParameterHandler.QueryName<>(converter, encoded); // 实例化QueryName对象 } else if (annotation instanceof QueryMap) { // 当前参数类型注解为 #@QueryMap validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 gotQueryMap = true; // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (!Map.class.isAssignableFrom(rawParameterType)) { // 传入参数非Map类型 抛出参数异常 必须传入Map throw parameterError(method, p, "@QueryMap parameter type must be Map."); Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); // 当前参数的类型超类获取 if (!(mapType instanceof ParameterizedType)) { // 非参数化类型 抛出参数错误 throw parameterError(method, p, "Map must include generic types (e.g., Map<String, String>)"); ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); // 获取当前Map中key的具体类型值 if (String.class != keyType) { throw parameterError(method, p, "@QueryMap keys must be of type String: " + keyType); Type valueType = Utils.getParameterUpperBound(1, parameterizedType); // 获取当前Map中value的具体类型值 Converter<?, String> valueConverter = retrofit.stringConverter(valueType, annotations); // 将转换器工厂替换成String return new ParameterHandler.QueryMap<>(valueConverter, ((QueryMap) annotation).encoded()); // 实例化QueryMap对象 } else if (annotation instanceof Header) {// 当前参数注解为 @Header validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 Header header = (Header) annotation; String name = header.value(); Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (Iterable.class.isAssignableFrom(rawParameterType)) { // 集合类型 if (!(type instanceof ParameterizedType)) { throw parameterError(method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + "<String>)"); ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);// 获取当前参数类型 Converter<?, String> converter = retrofit.stringConverter(iterableType, annotations); // 将转换器工厂替换成String return new ParameterHandler.Header<>(name, converter).iterable(); } else if (rawParameterType.isArray()) {// 数组类型 Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); // 获取当前参数承载类对象 Converter<?, String> converter = retrofit.stringConverter(arrayComponentType, annotations); // 将转换器工厂替换成String return new ParameterHandler.Header<>(name, converter).array(); // 实例化Header对象 } else { // 其他情况 Converter<?, String> converter = retrofit.stringConverter(type, annotations); // 将转换器工厂替换成String return new ParameterHandler.Header<>(name, converter); // 实例化Header对象 } else if (annotation instanceof HeaderMap) { // 当前参数注解为 @HeaderMap validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (!Map.class.isAssignableFrom(rawParameterType)) { //非Map类 throw parameterError(method, p, "@HeaderMap parameter type must be Map."); Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); if (!(mapType instanceof ParameterizedType)) { // 非参数化类型 throw parameterError(method, p, "Map must include generic types (e.g., Map<String, String>)"); ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); // 获取key对应的数据类型类 if (String.class != keyType) { throw parameterError(method, p, "@HeaderMap keys must be of type String: " + keyType); Type valueType = Utils.getParameterUpperBound(1, parameterizedType); // 获取value对应的数据类型类 Converter<?, String> valueConverter = retrofit.stringConverter(valueType, annotations); // 将转换器工厂替换成String return new ParameterHandler.HeaderMap<>(valueConverter); // 实例HeaderMap对象 } else if (annotation instanceof Field) { // 当前参数注解为 @Field validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 if (!isFormEncoded) { // 非表单提交 不能使用 throw parameterError(method, p, "@Field parameters can only be used with form encoding."); Field field = (Field) annotation; String name = field.value(); boolean encoded = field.encoded(); gotField = true; // 有表单提交 Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (Iterable.class.isAssignableFrom(rawParameterType)) {// 集合类型 if (!(type instanceof ParameterizedType)) { throw parameterError(method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + "<String>)"); ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); // 获取集合类型对应的具体类 Converter< ?, String> converter = retrofit.stringConverter(iterableType, annotations); // 将转换器工厂替换成String return new ParameterHandler.Field<>(name, converter, encoded).iterable(); // 实例化Field对象 } else if (rawParameterType.isArray()) { // 数组类型 Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); // 获取数组类型的具体类 Converter<?, String> converter = retrofit.stringConverter(arrayComponentType, annotations); // 将转换器工厂替换成String return new ParameterHandler.Field<>(name, converter, encoded).array(); // 实例化Field对象 } else { // 其他情况 Converter<?, String> converter = retrofit.stringConverter(type, annotations); // 将转换器工厂替换成String return new ParameterHandler.Field<>(name, converter, encoded); // 实例化Field对象 } else if (annotation instanceof FieldMap) { // 当前参数注解为 @FieldMap validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 if (!isFormEncoded) { // 非表单请求 throw parameterError(method, p, "@FieldMap parameters can only be used with form encoding."); Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (!Map.class.isAssignableFrom(rawParameterType)) { // 非Map类型 throw parameterError(method, p, "@FieldMap parameter type must be Map."); Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); // 当前类的超类类型获取 if (!(mapType instanceof ParameterizedType)) { // 非参数化类型 throw parameterError(method, p, "Map must include generic types (e.g., Map<String, String>)"); ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); // 获取参数Key具体类型类 if (String.class != keyType) { throw parameterError(method, p, "@FieldMap keys must be of type String: " + keyType); Type valueType = Utils.getParameterUpperBound(1, parameterizedType); // 获取参数value具体类型类 Converter<?, String> valueConverter = retrofit.stringConverter(valueType, annotations); // 将转换器工厂替换成String gotField = true; // 有表单提交 return new ParameterHandler.FieldMap<>(valueConverter, ((FieldMap) annotation).encoded());//实例化FieldMap对象 } else if (annotation instanceof Part) { //当前参数注解为 @Part validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 if (!isMultipart) { // 非表单提交(带有文件) throw parameterError(method, p, "@Part parameters can only be used with multipart encoding."); Part part = (Part) annotation; gotPart = true; // 有part提交 String partName = part.value(); Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 if (partName.isEmpty()) { // value值为空 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (Iterable.class.isAssignableFrom(rawParameterType)) { // 集合类型 if (!(type instanceof ParameterizedType)) { throw parameterError(method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + "<String>)"); ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);// 集合类型具体类型类 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (!MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(iterableType))) { // 判断当前参数是什么具体类型的 throw parameterError(method, p, "@Part annotation must supply a name or use MultipartBody.Part parameter type."); // multipartBuilder.addPart(part); return ParameterHandler.RawPart.INSTANCE.iterable(); // 实例化Part对象 将value值遍历添加到Part中 } else if (rawParameterType.isArray()) { // 数组类型 Class<?> arrayComponentType = rawParameterType.getComponentType(); // 获取数组具体类型 String[] 拿到之后 String // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (!MultipartBody.Part.class.isAssignableFrom(arrayComponentType)) { throw parameterError(method, p, "@Part annotation must supply a name or use MultipartBody.Part parameter type."); return ParameterHandler.RawPart.INSTANCE.array(); // 实例化Part对象 将value值遍历添加到Part中 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 } else if (MultipartBody.Part.class.isAssignableFrom(rawParameterType)) { return ParameterHandler.RawPart.INSTANCE; // 实例化RawPart对象 } else {// 其他情况 throw parameterError(method, p, "@Part annotation must supply a name or use MultipartBody.Part parameter type."); } else { // value不为空 Headers headers = Headers.of("Content-Disposition", "form-data; name=\"" + partName + "\"", "Content-Transfer-Encoding", part.encoding()); // 补充请求头文件信息 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (Iterable.class.isAssignableFrom(rawParameterType)) { // 集合类型 if (!(type instanceof ParameterizedType)) { // 非参数化类型 throw parameterError(method, p, rawParameterType.getSimpleName() + " must include generic type (e.g., " + rawParameterType.getSimpleName() + "<String>)"); ParameterizedType parameterizedType = (ParameterizedType) type; Type iterableType = Utils.getParameterUpperBound(0, parameterizedType); // 获取当前集合类型的具体类型 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(iterableType))) { // 判断当前参数是什么具体类型的 throw parameterError(method, p, "@Part parameters using the MultipartBody.Part must not " + "include a part name in the annotation."); Converter<?, RequestBody> converter = retrofit.requestBodyConverter(iterableType, annotations, methodAnnotations); return new ParameterHandler.Part<>(headers, converter).iterable(); } else if (rawParameterType.isArray()) { Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType()); // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (MultipartBody.Part.class.isAssignableFrom(arrayComponentType)) { throw parameterError(method, p, "@Part parameters using the MultipartBody.Part must not " + "include a part name in the annotation."); // 转换器进行处理 Converter<?, RequestBody> converter = retrofit.requestBodyConverter(arrayComponentType, annotations, methodAnnotations); return new ParameterHandler.Part<>(headers, converter).array();//实例化Part对象 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 } else if (MultipartBody.Part.class.isAssignableFrom (rawParameterType)) { throw parameterError(method, p, "@Part parameters using the MultipartBody.Part must not " + "include a part name in the annotation."); } else { // 转换器进行处理 Converter<?, RequestBody> converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations); return new ParameterHandler.Part<>(headers, converter);//实例化Part对象 } else if (annotation instanceof PartMap) { // 当前参数注解为 @PartMap validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 if (!isMultipart) { // 非表单提交(含有文件提交) throw parameterError(method, p, "@PartMap parameters can only be used with multipart encoding."); gotPart = true; Class<?> rawParameterType = Utils.getRawType(type); // 判断当前参数是什么具体类型的 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (!Map.class.isAssignableFrom(rawParameterType)) { throw parameterError(method, p, "@PartMap parameter type must be Map."); Type mapType = Utils.getSupertype(type, rawParameterType, Map.class); // 获取超类类型 if (!(mapType instanceof ParameterizedType)) { throw parameterError(method, p, "Map must include generic types (e.g., Map<String, String>)"); ParameterizedType parameterizedType = (ParameterizedType) mapType; Type keyType = Utils.getParameterUpperBound(0, parameterizedType); // 获取参数map中key的具体类型类 if (String.class != keyType) { throw parameterError(method, p, "@PartMap keys must be of type String: " + keyType); Type valueType = Utils.getParameterUpperBound(1, parameterizedType); // 获取参数map中value的具体类型类 // isAssignableFrom 集合类型 父类 对 子类进行判断是否是属于同一类的 // instanceof 子类 对 父类 进行判断是否属于同一类 if (MultipartBody.Part.class.isAssignableFrom(Utils.getRawType(valueType))) { // 判断当前参数是什么具体类型的 throw parameterError(method, p, "@PartMap values cannot be MultipartBody.Part. " + "Use @Part List<Part> or a different value type instead."); // 转换器进行处理 Converter<?, RequestBody> valueConverter = retrofit.requestBodyConverter(valueType, annotations, methodAnnotations); PartMap partMap = (PartMap) annotation; return new ParameterHandler.PartMap<>(valueConverter, partMap.encoding()); // 实例化PartMap对象 } else if (annotation instanceof Body) { // 当前参数注解为 @Body validateResolvableType(p, type); // 如果方法的返回结果包含了泛型表达式、泛型、泛型数组,就抛出异常 if (isFormEncoded || isMultipart) { // @Body注解不能与表单提交一起使用 throw parameterError(method, p, "@Body parameters cannot be used with form or multi-part encoding."); if (gotBody) { // 不能使用多个@Body注解 throw parameterError(method, p, "Multiple @Body method annotations found."); Converter<?, RequestBody> converter; try { // 转换器进行处理 converter = retrofit.requestBodyConverter(type, annotations, methodAnnotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw parameterError(method, e, p, "Unable to create @Body converter for %s", type); gotBody = true; return new ParameterHandler.Body<>(converter); // 实例化Body对象 return null; // Not a Retrofit annotation.
Class<?> rawParameterType = Utils.getRawType(type); 获取当前方法参数的具体类型
static Class<?> getRawType(Type type) { checkNotNull(type, "type == null"); // 判空处理 if (type instanceof Class<?>) { // 如果是正常类参数 直接返回 例: String 直接返回 // Type is a normal class. return (Class<?> ) type; if (type instanceof ParameterizedType) { // 判断是否属于泛型参数 例: List<String> : true List:false ParameterizedType parameterizedType = (ParameterizedType) type; Type rawType = parameterizedType.getRawType(); // 获取泛型参数的类或者接口类型 eg:List<String> 返回 List if (!(rawType instanceof Class)) throw new IllegalArgumentException(); // 如果返回的类不是正常类 抛出异常 return (Class<?>) rawType; // 返回当前类型 List if (type instanceof GenericArrayType) { // 判断是否是通用数据类型 // 无论从左向右有几个[]并列,这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值。 Type componentType = ((GenericArrayType) type).getGenericComponentType(); return Array.newInstance(getRawType(componentType), 0).getClass(); // 由于是数组,拿取第一个位置就能知道是什么类 if (type instanceof TypeVariable) { // 可变类型 return Object.class; if (type instanceof WildcardType) { // 通配符类型 ?,? extends Number,? super Number return getRawType(((WildcardType) type).getUpperBounds()[0]); // 获取通配符表达式对象的泛型限定的上边界的类型 // 上面类型都没有 则抛出异常 throw new IllegalArgumentException("Expected a Class, ParameterizedType, or " + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
上面泛型类型的分类
下面是每个类型对应的方法的作用
new RequestFactory(this);
RequestFactory(Builder builder) { // 根据之前的相关注解的解析 实例化请求工厂类 method = builder.method; // 方法 baseUrl = builder.retrofit.baseUrl; // 请求头 url httpMethod = builder.httpMethod; // 请求方法 例如: get relativeUrl = builder.relativeUrl; // 请求路径url headers = builder.headers; // 请求头数据 contentType = builder.contentType; // 内容类型 hasBody = builder.hasBody; // 是否有请求体 isFormEncoded = builder.isFormEncoded; // 是否是表单提交 isMultipart = builder.isMultipart; // 是否是表单提交(含有文件) parameterHandlers = builder.parameterHandlers; //所有参数数据
ServiceMethod 中调用 new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory) { // 根据当前方法的返回参数创建请求适配器 CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method); Type responseType = callAdapter.responseType(); // 获取响应数据类型 if (responseType == Response.class || responseType == okhttp3.Response.class) { // 不能是Response类 throw methodError(method, "'" + Utils.getRawType(responseType).getName() + "' is not a valid response body type. Did you mean ResponseBody?"); // 请求方法是请求头 并且方法返回不为Void if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) { throw methodError(method, "HEAD method must use Void as response type."); // 创建响应转换器 根据响应类型创建转换器 Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType); okhttp3.Call.Factory callFactory = retrofit.callFactory; // callFactory 就是开始初始化的 OkHttpClient // 根据上面得到的信息进行实例化 HttpServiceMethod对象 return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
createCallAdapter()
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter( Retrofit retrofit, Method method) { Type returnType = method.getGenericReturnType(); // 获取方法的返回类型 Annotation[] annotations = method.getAnnotations(); // 获取作用于方法上面的所有注解 try { //noinspection unchecked 获取请求适配器 return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations); } catch (RuntimeException e) { // Wide exception range because factories are user code. throw methodError(method, e, "Unable to create call adapter for %s", returnType);
Retrofit # callAdapter(returnType, annotations);
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) { return nextCallAdapter(null, returnType, annotations); public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) { checkNotNull(returnType, "returnType == null"); // 判空处理 checkNotNull(annotations, "annotations == null"); // 判空处理 // call适配器工厂的第二个开始 根据上面的源码可以知道 // 第一个是我自己添加的 RxJava2CallAdapterFactory // 第二个是系统自己默认的 platform.defaultCallAdapterFactories(callbackExecutor) 通过handler会在主线程进行执行 // callbackExecutor == null ? ExecutorCallAdapterFactory : DefaultCallAdapterFactory int start = callAdapterFactories.indexOf(skipPast) + 1; // 从 0 开始 获取 for (int i = start, count = callAdapterFactories.size(); i < count; i++) { CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this); 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(callAdapterFactories.get(i).getClass().getName()); builder.append('\n'); builder.append(" Tried:"); for (int i = start, count = callAdapterFactories.size(); i < count; i++) { builder.append("\n * ").append(callAdapterFactories.get(i).getClass().getName()); throw new IllegalArgumentException(builder.toString());
创建响应转换器
Retrofit # responseBodyConverter()
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) { return nextResponseBodyConverter(null, type, annotations); public <T> Converter<ResponseBody, T> nextResponseBodyConverter( @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) { checkNotNull(type, "type == null"); // 判空处理 checkNotNull(annotations, "annotations == null"); // 判空处理 int start = converterFactories.indexOf(skipPast) + 1; // 从转换器的第一个开始获取 for (int i = start, count = converterFactories.size(); i < count; i++) { converterFactories.add(new BuiltInConverters()); 0 converterFactories.addAll(this.converterFactories); 1 WGsonConverterFactory 初始化的时候添加的Gson转换器工厂 converterFactories.addAll(platform.defaultConverterFactories()); 2 系统默认的转换器工厂 >= 7.0 返回为1 其他 null // 初始化添加的 获取默认就初始化 一定不为空 如果大于等于7.0 就是这个工厂 OptionalConverterFactory 进行实例化 Converter<ResponseBody, ?> converter = converterFactories. get(i).responseBodyConverter(type, annotations, this); if (converter != null) { //noinspection unchecked return (Converter<ResponseBody, T>) converter; // 拿取失败就抛出异常 StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ") .append(type) .append(".\n"); if (skipPast != null) { builder.append(" Skipped:"); for (int i = 0; i < start; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); builder.append('\n'); builder.append(" Tried:"); for (int i = start, count = converterFactories.size(); i < count; i++) { builder.append("\n * ").append(converterFactories.get(i).getClass().getName()); throw new IllegalArgumentException(builder.toString());
到这里表示就上面的代码已经将所有的方法相关的数据进行解析了,数据值也进行了缓存,下面可以开始去做请求操作了。开始执行invoke的操作,下面我们看一下invoke里面具体做了什么操作。
loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
ServiceMethod # invoke() 方法仅在 HttpServiceMethod类中进行实现,所以
HttpServiceMethod # invoke()
@Override ReturnT invoke(Object[] args) { return callAdapter.adapt( new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
先看方法里面,创建了一个OkHttpCall的实例, OkHttpCall implements Call OkHttpCall实现了Call的接口,这个Call是Retrofit的Call
OkHttpCall(RequestFactory requestFactory, Object[] args, okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) { this.requestFactory = requestFactory; // 之前解析的请求工厂 this.args = args; // 参数 this.callFactory = callFactory; // call工厂 this.responseConverter = responseConverter; // 响应转换器 // 进行复制初始化操作
CallAdapter # adapt();
如果我这里暂时使用RxJava2CallAdapterFactory,在执行get()方法的时候 创建RxJava2CallAdapter类
@Override public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) { Class<?> rawType = getRawType(returnType); if (rawType == Completable.class) { // 返回类型是否是Completable类 // Completable is not parameterized (which is what the rest of this method deals with) so it // can only be created with a single configuration. return new RxJava2CallAdapter(Void.class, scheduler, false, true, false, false, false, true); boolean isFlowable = rawType == Flowable.class; boolean isSingle = rawType == Single.class; boolean isMaybe = rawType == Maybe.class; if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) { // 不是这些类型就返回null 接着让默认请求适配器去处理 return null; boolean isResult = false; boolean isBody = false; Type responseType; if (!(returnType instanceof ParameterizedType)) { // 非参数化类型 String name = isFlowable ? "Flowable" : isSingle ? "Single" : "Observable"; throw new IllegalStateException(name + " return type must be parameterized" + " as " + name + "<Foo> or " + name + "<? extends Foo>"); Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType); // 获取当前返回类型的具体类型 Class<?> rawObservableType = getRawType( observableType); if (rawObservableType == Response.class) { // 是Response if (!(observableType instanceof ParameterizedType)) { // 非参数化类型 抛出异常 throw new IllegalStateException("Response must be parameterized" + " as Response<Foo> or Response<? extends Foo>"); responseType = getParameterUpperBound(0, (ParameterizedType) observableType); // 获取当前返回类型的具体类型 } else if (rawObservableType == Result.class) { // 是Result if (!(observableType instanceof ParameterizedType)) { // 非参数化类型 抛出异常 throw new IllegalStateException("Result must be parameterized" + " as Result<Foo> or Result<? extends Foo>"); responseType = getParameterUpperBound(0, (ParameterizedType) observableType); // 获取当前返回类型的具体类型 isResult = true; } else { responseType = observableType; isBody = true; // 实例化RxJava2CallAdapter对象 return new RxJava2CallAdapter(responseType, scheduler, isResult, isBody, isFlowable, isSingle, isMaybe, false);
开始执行adapt()方法。 由上面的代码可知 isBody:true 其他均为false
@Override public <R> Object adapt(Call<R> call) { Observable<Response<R>> responseObservable = new CallObservable<>(call); // 创建一个被观察者 Observable<?> observable; if (isResult) { observable = new ResultObservable<>(responseObservable); } else if (isBody) { // 会进入到这个判断中 observable = new BodyObservable<>(responseObservable); } else { observable = responseObservable; if (scheduler != null) { observable = observable.subscribeOn(scheduler); if (isFlowable) { return observable.toFlowable(BackpressureStrategy.LATEST); if (isSingle) { return observable.singleOrError(); if (isMaybe) { return observable.singleElement(); if (isCompletable) { return observable.ignoreElements(); return observable; // 然后直接返回 等待RxJava进入调用流程 会从subscribeActual调用上来
假设现在的RxJava已经开始调用这个接口方法了,调用到Retrofit中的subscribeActual中了,这个时候开始执行BodyObservable方法。
@Override protected void subscribeActual(Observer<? super T> observer) { upstream.subscribe(new BodyObserver<>(observer)); // 开始调用upstream中的subscribe。upstream这个方法我们看源码是知道是谁的 // 从这里可以知道 这里调用的是创建的时候的类,我们看到上面的代码有这个方法的调用 BodyObservable(Observable<Response<T>> upstream) { this.upstream = upstream;
Observable<Response> responseObservable = new CallObservable<>(call); // 创建一个被观察者
new BodyObservable<>(responseObservable);
所以代码追溯到 CallObservable的subscribeActual
CallObservable # subscribeActual
@Override protected void subscribeActual(Observer<? super Response<T>> observer) { // Since Call is a one-shot type, clone it for each new observer. Call<T> call = originalCall.clone(); // 对原始的请求数据进行克隆 observer.onSubscribe(new CallDisposable(call)); // 开始执行onSubscribe方法 boolean terminated = false; try { Response<T> response = call.execute(); // 请求开始执行 会进行阻塞 if (!call.isCanceled()) { // 请求未被取消 拿到数据之后进行传递 执行onNext方法 observer.onNext(response); if (!call.isCanceled()) { // 未被取消 则执行完成 terminated = true; observer.onComplete(); } catch (Throwable t) { Exceptions.throwIfFatal(t); if (terminated) { RxJavaPlugins.onError( t); // 执行异常方法 } else if (!call.isCanceled()) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner));// 执行异常方法
Response response = call.execute(); 这个地方的Call在执行adapt(Call)传进来的。所以这个Call的实体是OkHttpCall,execute的实现方法在OkHttpCall类中。
@Override public Response<T> execute() throws IOException { okhttp3.Call call; synchronized (this) { // 加锁处理 防止重复执行当前请求 if (executed) throw new IllegalStateException("Already executed."); executed = true; if (creationFailure != null) { // 创建RealCall失败 出现了异常 进行处理 if (creationFailure instanceof IOException) { throw (IOException) creationFailure; } else if (creationFailure instanceof RuntimeException) { throw (RuntimeException) creationFailure; } else { throw (Error) creationFailure; call = rawCall; if (call == null) { // 第一次执行时 为null try { call = rawCall = createRawCall(); // 创建一个RealCall } catch (IOException | RuntimeException | Error e) { throwIfFatal(e); // Do not assign a fatal error to creationFailure. creationFailure = e; throw e; if (canceled) { call.cancel(); return parseResponse(call.execute()); // 执行网络请求 和 解析响应
createRawCall();
private okhttp3.Call createRawCall() throws IOException { // callFactory 就是之前初始化的OkHttpClient okhttp3.Call call = callFactory.newCall(requestFactory.create(args)); if (call == null) { throw new NullPointerException("Call.Factory returned null."); return call;
callFactory.newCall(requestFactory.create(args)); 现在请求执行到了OkHttp
@Override public Call newCall(Request request) { return RealCall.newRealCall(this, request, false /* for web socket */);
OkHttp后面的代码就不进行分析了,上一篇已经进行了分析,有兴趣的可以爬楼看看(▽);
parseResponse(call.execute()); // 执行网络请求 和 解析响应
call.execute();也是调用OkHttp中RealCall的execute()方法。
下面我们在来看看parseResponse()拿到请求数据之后的解析工作吧OkHttpCall # parseResponse
Response<T> 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) { // 请求成功情况 只是返回数据为null rawBody.close(); return Response.success(null, rawResponse); ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody); try { T body = responseConverter.convert(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;
由于我做了转换器的添加,所以代码执行到这里,
由于上面的requestBodyConverter方法里创建了WGsonRequestBodyConverter
@Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return new WGsonRequestBodyConverter<>(gson, adapter);
所以执行convert方法的时候执行的也是这个类里面的方法。
// 代码比较少 我就全部拿过来了 final class WGsonResponseBodyConverter<T> implements Converter<ResponseBody, T> { private final Gson gson; private final TypeAdapter<T> adapter; WGsonResponseBodyConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; @Override public T convert(ResponseBody value) throws IOException { JsonReader jsonReader = gson.newJsonReader(value.charStream()); // 将Reader数据转为JsonReader try { T result = adapter.read(jsonReader); // 开始阅读JsonReader对象 if (jsonReader.peek() != JsonToken.END_DOCUMENT) { throw new JsonIOException("JSON document was not fully consumed."); return result; } finally { value.close();
gson.newJsonReader(value.charStream()); 调用到Gson # newJsonReader
public JsonReader newJsonReader(Reader reader) { JsonReader jsonReader = new JsonReader(reader); // 对Reader进行成员参数赋值 jsonReader.setLenient(lenient); // 因为我在初始化的时候进行设置为true的操作 所以这个变量为true return jsonReader; // 返回JsonReader实例对象
实例化JsonReader对象
public JsonReader(Reader in) { if (in == null) { throw new NullPointerException("in == null"); this.in = in; // 进行成员参数赋值
adapter.read() 因为adapter需要去执行read方法 我们先需要了解adapter是怎么来的。
requestBodyConverter 方法中有getAdapter
public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) { // 获取缓存中的请求adapter是否存在,存在即返回 TypeAdapter<?> cached = typeTokenCache.get(type == null ? NULL_KEY_SURROGATE : type); if (cached != null) { return (TypeAdapter<T>) cached; // 本地线程缓冲中获取当前线程的请求数据信息 Map<TypeToken<?>, FutureTypeAdapter<?>> threadCalls = calls.get(); boolean requiresThreadLocalCleanup = false; // 是否清除本地线程缓冲数据 if (threadCalls == null) { // null 本地线程缓冲中不存在 threadCalls = new HashMap<TypeToken<?>, FutureTypeAdapter<?>>(); // 实例化一个hashmap calls.set(threadCalls); // 缓存至TLB中 requiresThreadLocalCleanup = true; // 进行清除 // the key and value type parameters always agree FutureTypeAdapter<T> ongoingCall = (FutureTypeAdapter<T>) threadCalls.get(type); // 获取当前返回类型的FutureTypeAdapter适配器 if (ongoingCall != null) { // 已经存在当前返回值的适配器 直接返回 return ongoingCall; try { // 当前FutureTypeAdapter适配器依旧为null 创建一个适配器 FutureTypeAdapter<T> call = new FutureTypeAdapter<T>( ); threadCalls.put(type, call); // 并将当前适配器与对应的type保存到HashMap中 // 在gson初始化的List<TypeAdapterFactory>中查找对应的TypeAdapter for (TypeAdapterFactory factory : factories) { // 开始进行遍历类型适配器的工厂 TypeAdapter<T> candidate = factory.create(this, type); // 获取到解析适配器 if (candidate != null) { call.setDelegate(candidate); // 设置参数 typeTokenCache.put(type, candidate); // 存入缓存Map集合中 return candidate; throw new IllegalArgumentException("GSON cannot handle " + type); } finally { threadCalls.remove(type); if (requiresThreadLocalCleanup) { calls.remove();
GsonBuilder
public Gson create() { // 这里的factories是为null hierarchyFactories也为null List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(this.factories.size() + this.hierarchyFactories.size() + 3); factories.addAll(this.factories); Collections.reverse(factories); List<TypeAdapterFactory> hierarchyFactories = new ArrayList<TypeAdapterFactory>(this.hierarchyFactories); Collections.reverse(hierarchyFactories); factories.addAll(hierarchyFactories); // 添加了三个TypeAdapter // factories.add(TypeAdapters.newFactory(Date.class, dateTypeAdapter)); 日期类型 // factories.add(TypeAdapters.newFactory(Timestamp.class, timestampTypeAdapter)); 时间戳 // factories.add(TypeAdapters.newFactory(java.sql.Date.class, javaSqlDateTypeAdapter)); java数据库时间类型 addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, factories); return new Gson(excluder, fieldNamingPolicy, instanceCreators, serializeNulls, complexMapKeySerialization, generateNonExecutableJson, escapeHtmlChars, prettyPrinting, lenient, serializeSpecialFloatingPointValues, longSerializationPolicy, factories); // 开始初始化gson
new Gson();
Gson(final Excluder excluder, final FieldNamingStrategy fieldNamingStrategy, final Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy, List<TypeAdapterFactory> typeAdapterFactories) { this.constructorConstructor = new ConstructorConstructor(instanceCreators); this.excluder = excluder; this.fieldNamingStrategy = fieldNamingStrategy; this.serializeNulls = serializeNulls; this.generateNonExecutableJson = generateNonExecutableGson; this.htmlSafe = htmlSafe; this.prettyPrinting = prettyPrinting; this.lenient = lenient; List<TypeAdapterFactory> factories = new ArrayList<TypeAdapterFactory>(); // built-in type adapters that cannot be overridden factories.add(TypeAdapters.JSON_ELEMENT_FACTORY); factories.add(ObjectTypeAdapter.FACTORY); // the excluder must precede all adapters that handle user-defined types factories.add(excluder); // 排除器的添加 // user's type adapters 用户添加的类型 factories.addAll(typeAdapterFactories); // type adapters for basic platform types 基础类型 factories.add(TypeAdapters.STRING_FACTORY); factories.add(TypeAdapters.INTEGER_FACTORY); factories.add(TypeAdapters.BOOLEAN_FACTORY); factories.add(TypeAdapters.BYTE_FACTORY); factories.add(TypeAdapters.SHORT_FACTORY); TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy); factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter)); factories.add(TypeAdapters.newFactory(double.class, Double.class, doubleAdapter(serializeSpecialFloatingPointValues)) ); factories.add(TypeAdapters.newFactory(float.class, Float.class, floatAdapter(serializeSpecialFloatingPointValues))); factories.add(TypeAdapters.NUMBER_FACTORY); factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY); factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY); factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter))); factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter))); factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY); factories.add(TypeAdapters.CHARACTER_FACTORY); factories.add(TypeAdapters.STRING_BUILDER_FACTORY); factories.add(TypeAdapters.STRING_BUFFER_FACTORY); factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL)); factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER)); factories.add(TypeAdapters.URL_FACTORY); factories.add(TypeAdapters.URI_FACTORY); factories.add(TypeAdapters.UUID_FACTORY); factories.add(TypeAdapters.CURRENCY_FACTORY); factories.add(TypeAdapters.LOCALE_FACTORY); factories.add(TypeAdapters.INET_ADDRESS_FACTORY); factories.add(TypeAdapters.BIT_SET_FACTORY); factories.add(DateTypeAdapter.FACTORY); factories.add(TypeAdapters.CALENDAR_FACTORY); factories.add(TimeTypeAdapter.FACTORY); factories.add(SqlDateTypeAdapter.FACTORY); factories.add(TypeAdapters.TIMESTAMP_FACTORY); factories.add(ArrayTypeAdapter.FACTORY); factories.add(TypeAdapters.CLASS_FACTORY); // type adapters for composite and user-defined types factories.add(new CollectionTypeAdapterFactory(constructorConstructor)); // Colloction类型 // Map集合类型 factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization)); // json注解类型 this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor); factories.add(jsonAdapterFactory); // 枚举类型 factories.add(TypeAdapters.ENUM_FACTORY); // 反射类型 factories.add(new ReflectiveTypeAdapterFactory( constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory)); this.factories = Collections.unmodifiableList(factories);
上面的代码拿到Adapter,开始进行json数据的解析
T result = adapter.read(jsonReader)
因为我的项目导入是使用Retrofit进行导入的 所以我查看我的gson版本是2.8.2
ReflectiveTypeAdapterFactory查看这个类的解析用了些什么方法
@Override public T read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { // 得到 JsonToken.BEGIN_OBJECT false 不进入当前判断 in.nextNull(); return null; T instance = constructor.construct(); // 初始化操作 try { in.beginObject(); // 开始解析开始对象 while (in.hasNext()) { // 是否有下一个 第一次到这里 返回 PEEKED_DOUBLE_QUOTED_NAME true String name = in.nextName(); // 获取name信息 BoundField field = boundFields.get(name); // 根据集合去获取里面的字段信息 if (field == null || !field.deserialized) { // 如果字段为null 或者 字段不能反序列化 in.skipValue(); // 跳过value值 因为解析的类对象中不存在当前字段 || 或者这个字段可以 不管不能反序列化 } else { field.read(in, instance); // 这里开始执行到 根据字段类型去读取value值 } catch (IllegalStateException e) { throw new JsonSyntaxException(e); } catch (IllegalAccessException e) { throw new AssertionError(e); in.endObject(); return instance;
JsonReader # peek();
public JsonToken peek() throws IOException { int p = peeked; // 之前的代码未进行赋值操作 所以这个为默认值 PEEKED_NONE if (p == PEEKED_NONE) { p = doPeek(); // 进入到doPeek()中 根据上面示例json数据 可以知道这个返回为 PEEKED_BEGIN_OBJECT 对象开始标志 switch (p) { case PEEKED_BEGIN_OBJECT: return JsonToken.BEGIN_OBJECT; // 开始对象解析 case PEEKED_END_OBJECT: return JsonToken.END_OBJECT; case PEEKED_BEGIN_ARRAY: return JsonToken.BEGIN_ARRAY; case PEEKED_END_ARRAY: return JsonToken.END_ARRAY; case PEEKED_SINGLE_QUOTED_NAME: case PEEKED_DOUBLE_QUOTED_NAME: case PEEKED_UNQUOTED_NAME: return JsonToken.NAME; // 解析json名称 case PEEKED_TRUE: case PEEKED_FALSE: return JsonToken.BOOLEAN; case PEEKED_NULL: return JsonToken.NULL; case PEEKED_SINGLE_QUOTED: case PEEKED_DOUBLE_QUOTED: case PEEKED_UNQUOTED: case PEEKED_BUFFERED: return JsonToken.STRING; // 解析String case PEEKED_LONG: case PEEKED_NUMBER: return JsonToken.NUMBER; case PEEKED_EOF: return JsonToken.END_DOCUMENT; default: throw new AssertionError();
JsonReader # doPeek(); 如果返回之后的json = {“username”:“hello”,“age”:18}
int doPeek() throws IOException { // 第一次进入到这个方法 stack的长度为32 stackSize值为1 stack[0] = EMPTY_DOCUMENT; int peekStack = stack[stackSize - 1]; // 32 length [0] = EMPTY_DOCUMENT 第二次进来 [1] = EMPTY_OBJECT if (peekStack == JsonScope.EMPTY_ARRAY) { stack[stackSize - 1] = JsonScope.NONEMPTY_ARRAY; } else if (peekStack == JsonScope.NONEMPTY_ARRAY) { // Look for a comma before the next element. int c = nextNonWhitespace(true); // 获取下一个非空白字符 switch (c) { case ']': return peeked = PEEKED_END_ARRAY; // 集合结束字符 case ';': checkLenient(); // fall-through case ',': break; default: throw syntaxError("Unterminated array"); } else if (peekStack == JsonScope.EMPTY_OBJECT || peekStack == JsonScope.NONEMPTY_OBJECT) { // 第二次执行 hasNext进入到这个判断中 stack[stackSize - 1] = JsonScope.DANGLING_NAME; // Look for a comma before the next element. 表示上一个数值已经被解析完成 说明是非空对象进入 if (peekStack == JsonScope.NONEMPTY_OBJECT) { // EMPTY_OBJECT 第二次开始的时候是这个值 判断不能进入 int c = nextNonWhitespace(true); // 获取下一个非空白字符 switch (c) { case '}': return peeked = PEEKED_END_OBJECT; case ';': checkLenient(); // fall-through case ',': // [19] = ',' 不管 pos=20 break; default: throw syntaxError("Unterminated object"); int c = nextNonWhitespace(true); // 获取下一个非空白字符 拿到第二个字符 双引号 switch (c) { case '"': return peeked = PEEKED_DOUBLE_QUOTED_NAME; // [20] = '"' pos=21 case '\'': checkLenient(); return peeked = PEEKED_SINGLE_QUOTED_NAME; case '}': if (peekStack != JsonScope.NONEMPTY_OBJECT) { return peeked = PEEKED_END_OBJECT; } else { throw syntaxError("Expected name"); default: checkLenient(); pos--; // Don't consume the first character in an unquoted string. if (isLiteral((char) c)) { return peeked = PEEKED_UNQUOTED_NAME; } else { throw syntaxError("Expected name"); } else if (peekStack == JsonScope.DANGLING_NAME) { // 第一个name解析之后 进入到这个判断中 在上面有进行更改 stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT; // 改为非空对象 // Look for a colon before the value. int c = nextNonWhitespace(true); // 获取下一个非空白字符 pos = 11 switch (c) { case ':': // 下一个字符是 : break; case '=': // 下一个字符是 = checkLenient(); // 判断lenient == true if ((pos < limit || fillBuffer(1)) && buffer[pos] == '>') { // 判断错误 不管这里面的代码 pos++; break; default: throw syntaxError("Expected ':'"); } else if (peekStack == JsonScope.EMPTY_DOCUMENT) { // 第一次执行会进到这个判断语句 if (lenient) { // 这个在初始化的时候设置为true consumeNonExecutePrefix(); // 使用非执行前缀(如果存在)。对开始执行的pos值进行操作 pos = 0 stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT; // 返回类容不为空的标志 等待下一次进入执行 } else if (peekStack == JsonScope.NONEMPTY_DOCUMENT) { int c = nextNonWhitespace(false); // 获取下一个非空白字符 if (c == -1) { return peeked = PEEKED_EOF; } else { checkLenient(); pos--; } else if (peekStack == JsonScope.CLOSED) { throw new IllegalStateException("JsonReader is closed"); // DANGLING_NAME 这个判断下来是 : pos = 11 拿到 第三个 " int c = nextNonWhitespace(true); // 拿取到第一个可用字符 根据示例可知 第一次执行这个方法之后拿到的字符为 { switch (c) { case ']': // 如果上一个字符是 [ 则 集合结束字符 if (peekStack == JsonScope.EMPTY_ARRAY) { return peeked = PEEKED_END_ARRAY; // fall-through to handle ",]" case ';': case ',': // In lenient mode, a 0-length literal in an array means 'null'. 在宽松模式下,数组中长度为0的文字表示“null”。 if (peekStack == JsonScope.EMPTY_ARRAY || peekStack == JsonScope.NONEMPTY_ARRAY) { checkLenient(); // 检查lenient是否为true pos--; return peeked = PEEKED_NULL; // 设置为PEEKED_NULL } else { // 不是期望值 throw syntaxError("Unexpected value"); case '\'': checkLenient(); // 检查lenient是否为true return peeked = PEEKED_SINGLE_QUOTED; // 单引号返回 case '"': return peeked = PEEKED_DOUBLE_QUOTED; // 双引号返回 case '[': return peeked = PEEKED_BEGIN_ARRAY; // 集合开始 case '{': return peeked = PEEKED_BEGIN_OBJECT; // 对象开始 default: // 上面这些字符都没有 可能是其他字符 pos = 27 字符为 c = ‘1’ pos--; // Don't consume the first character in a literal value. pos = 26 int result = peekKeyword(); // 关键字处理 if (result != PEEKED_NONE) { return result; result = peekNumber(); // 数字处理 if (result != PEEKED_NONE) { return result; if (!isLiteral(buffer[pos])) { // 如果是其他字符 throw syntaxError("Expected value"); checkLenient(); // 检查lenient是否为true return peeked = PEEKED_UNQUOTED; // 未引述
JsonReader # nextNonWhitespace()
返回流中的下一个字符,该字符既不是空格,也不是注释的一部分。返回时,返回的字符始终位于缓冲区[pos-1];这意味着调用者总是可以通过减少pos来推回返回的字符。
private int nextNonWhitespace(boolean throwOnEof) throws IOException { char[] buffer = this.buffer; int p = pos; // 0 int l = limit; // 0 while (true) { if (p == l) { pos = p; if (!fillBuffer(1)) { // 获取数据基础信息 当前位置 和 数据长度 break; p = pos; l = limit; int c = buffer[p++]; // fillBuffer中pos++ = 1,即p = 1; buffer[1] 拿取第二个数据 if (c == '\n') { // 换行符 跳过 lineNumber++; lineStart = p; continue; } else if (c == ' ' || c == '\r' || c == '\t') { // 空格 不管 continue; if (c == '/') { // 斜杆 pos = p; if (p == l) { // 最后一个字符是斜杆 pos--; // push back '/' so it's still in the buffer when this method returns 将“/”推回,使其在该方法返回时仍在缓冲区中 boolean charsLoaded = fillBuffer(2); pos++; // consume the '/' again 再次使用“/”键 if (!charsLoaded) { return c; checkLenient(); // 检查设置是否为lenient == true char peek = buffer[pos]; // 如果上面的情况没有 pos = 1 switch (peek) { // 查看第一个数据是什么 根据上面示例返回为 " case '*': // 如果是 * 进行查找是否有 */ 表示是注释字符,如果找到就不管 跳过即可,如果找不到 抛出异常 // skip a /* c-style comment */ pos++; if (!skipTo("*/")) { throw syntaxError("Unterminated comment"); p = pos + 2; l = limit; continue; case '/': // 单行注释 // skip a // end-of-line comment pos++; skipToEndOfLine(); // 跳过这一行 p = pos; l = limit; continue; default: return c; } else if (c == '#') { // # 单行注释 pos = p; * Skip a # hash end-of-line comment. The JSON RFC doesn't * specify this behaviour, but it's required to parse * existing documents. See http://b/2571423. checkLenient(); // 检查是否为true skipToEndOfLine(); // 跳过这一行 不进行解析 p = pos; l = limit; } else { // 正常情况 非注释情况 拿到字符 pos = p; return c; if (throwOnEof) { // 如果上面都没有 直接抛出解析异常 throw new EOFException("End of input" + locationString()); } else { return -1;
JsonReader # fillBuffer()
private boolean fillBuffer(int minimum) throws IOException { char[] buffer = this.buffer; lineStart -= pos; // 最开始的时候 lineStart = 0 pos 没有不符合条件的字符 所以 pos = 0 if (limit != pos) { // limit 最开始也是 0 未进行赋值操作 limit -= pos; System.arraycopy(buffer, pos, buffer, 0, limit); // 进行数据的深拷贝 将前面不符合条件的字符进行覆盖处理 } else { limit = 0; // 开始进入下一步 pos = 0; int total; // 一次拿取1024字节 while ((total = in.read(buffer, limit, buffer.length - limit)) != -1) { // 开始读取数据流里面的数据 limit += total; // limit 唯一进行赋值的地方 // if this is the first read, consume an optional byte order mark (BOM) if it exists // 如果这是第一次读取,请使用可选的字节顺序标记(BOM)(如果存在) if (lineNumber == 0 && lineStart == 0 && limit > 0 && buffer[0] == '\ufeff') { pos++; lineStart++; minimum++; if (limit >= minimum) { // 数据读取完成 数据的长度大于最小程度 返回true return true; return false;
JsonReader # checkLenient() 检查设置是否为true
private void checkLenient() throws IOException { if (!lenient) { // false就一定会抛出异常 所以需要在初始化的时候设置为true throw syntaxError("Use JsonReader.setLenient(true) to accept malformed JSON");
JsonReader # peekKeyword()
private int peekKeyword() throws IOException { // Figure out which keyword we're matching against by its first character. char c = buffer[pos]; String keyword; String keywordUpper; int peeking; if (c == 't' || c == 'T') { // 对返回值t、T做处理 keyword = "true"; keywordUpper = "TRUE"; peeking = PEEKED_TRUE; } else if (c == 'f' || c == 'F') { // 对返回值F、f做处理 keyword = "false"; keywordUpper = "FALSE"; peeking = PEEKED_FALSE; } else if (c == 'n' || c == 'N') { // 对返回值n、N做处理 keyword = "null"; keywordUpper = "NULL"; peeking = PEEKED_NULL; } else { // 其他情况 return PEEKED_NONE; // Confirm that chars [1..length) match the keyword. 确认字符[1..length]与关键字匹配。 int length = keyword.length(); // 根据上面的判断 对关键字进行匹配 for (int i = 1; i < length; i++) { if (pos + i >= limit && !fillBuffer(i + 1)) { // 匹配超出指定长度 并且没有更多的数据了 return PEEKED_NONE; c = buffer[pos + i]; if (c != keyword.charAt(i) && c != keywordUpper.charAt(i)) { // 与关键字不符 return PEEKED_NONE; // 当前位置加上关键字长度小于最长数据 或者 还有更多的buffer数据 并且 关键字符之后是固定字符则匹配成功,否则匹配失败 if ((pos + length < limit || fillBuffer(length + 1)) && isLiteral(buffer[pos + length])) { return PEEKED_NONE; // Don't match trues, falsey or nullsoft! // We've found the keyword followed either by EOF or by a non-literal character. pos += length; // 匹配成功,pos做出处理 return peeked = peeking;
JsonReader # isLiteral()
private boolean isLiteral(char c) throws IOException { switch (c) { case '/': case '\\': case ';': case '#': case '=': checkLenient(); // fall-through case '{': case '}': case '[': case ']': case ':': case ',': case ' ': case '\t': case '\f': case '\r': case '\n': return false; default: return true;
JsonReader # peekNumber()
private int peekNumber() throws IOException { // Like nextNonWhitespace, this uses locals 'p' and 'l' to save inner-loop field access. char[] buffer = this.buffer; int p = pos; int l = limit; long value = 0; // Negative to accommodate Long.MIN_VALUE more easily. boolean negative = false; boolean fitsInLong = true; int last = NUMBER_CHAR_NONE; // 0 int i = 0; charactersOfNumber: for (; true; i++) { if (p + i == l) { // 如果当前遍历的数据已经到了拿取数据的最后位置 if (i == buffer.length) { // 是否没有数据流 // Though this looks like a well-formed number, it's too long to continue reading. Give up // and let the application handle this as an unquoted literal. return PEEKED_NONE; if (!fillBuffer(i + 1)) { // 开始从数据流中拿取数据 break; p = pos; l = limit; char c = buffer[p + i]; switch (c) { // - + e E . 0-9之间的字符进行处理 case '-': if (last == NUMBER_CHAR_NONE) { // 是否是第一次字符 negative = true; // 负号 last = NUMBER_CHAR_SIGN; continue; } else if (last == NUMBER_CHAR_EXP_E) { // 上一个字符是 E/e last = NUMBER_CHAR_EXP_SIGN; continue; return PEEKED_NONE; case '+': if (last == NUMBER_CHAR_EXP_E) { // 上一个字符是 E/e last = NUMBER_CHAR_EXP_SIGN; continue; return PEEKED_NONE; case 'e': case 'E': if (last == NUMBER_CHAR_DIGIT || last == NUMBER_CHAR_FRACTION_DIGIT) { // 上一个是数字 或者 分数数字 last = NUMBER_CHAR_EXP_E; continue; return PEEKED_NONE; case '.': if (last == NUMBER_CHAR_DIGIT) { // 上一个是数字 last = NUMBER_CHAR_DECIMAL; continue; return PEEKED_NONE; default: if (c < '0' || c > '9') { // 非数字的情况 if (!isLiteral(c)) { // 如果是其他字符 跳出循环 break charactersOfNumber; return PEEKED_NONE; if (last == NUMBER_CHAR_SIGN || last == NUMBER_CHAR_NONE) { // 上一个字符是 - 或者没有数据 value = -(c - '0'); // 拿到值 -1 last = NUMBER_CHAR_DIGIT; } else if (last == NUMBER_CHAR_DIGIT) { // 上一个字符是数字 if (value == 0) { // 0 在第一个不做处理 return PEEKED_NONE; // Leading '0' prefix is not allowed (since it could be octal). long newValue = value * 10 - (c - '0'); // 赋值处理 -18 fitsInLong &= value > MIN_INCOMPLETE_INTEGER || (value == MIN_INCOMPLETE_INTEGER && newValue < value); // 判断是否大于MIN_INCOMPLETE_INTEGER value = newValue; } else if (last == NUMBER_CHAR_DECIMAL) { // 上一个字符 . last = NUMBER_CHAR_FRACTION_DIGIT; } else if (last == NUMBER_CHAR_EXP_E || last == NUMBER_CHAR_EXP_SIGN) { // 上一个字符是 e/E | + last = NUMBER_CHAR_EXP_DIGIT; // We've read a complete number. Decide if it's a PEEKED_LONG or a PEEKED_NUMBER. // 我们是否读取到完整的数字 取决于PEEKED_LONG 或者是 PEEKED_NUMBER if (last == NUMBER_CHAR_DIGIT && fitsInLong && (value != Long.MIN_VALUE || negative) && (value!=0 || false==negative)) { peekedLong = negative ? value : -value; // 开始是否为负号的处理 18 pos += i; return peeked = PEEKED_LONG; } else if (last == NUMBER_CHAR_DIGIT || last == NUMBER_CHAR_FRACTION_DIGIT || last == NUMBER_CHAR_EXP_DIGIT) { peekedNumberLength = i; return peeked = PEEKED_NUMBER; } else { return PEEKED_NONE;
T instance = constructor.construct(); // 对象进行初始化 我们去看看这个是从哪里开始的
我们将代码向上进行追溯,发现是在create中进行的初始化操作,最终追溯到 Gson.getAdapter()方法中遍历factories,并执行了create方法
factory.create(this, type); ReflectiveTypeAdapterFactory # create(this, type)
因为之前的方法返回是 Observable<BaseJson>
type = com.lifeon.watch.base.http.interceptor.BaseJson<com.lifeon.watch.app.http.response.ResponseAppVersionInfo>
hashcode = 503989398
rawType = com.lifeon.watch.base.http.interceptor.BaseJson
@Override public <T> TypeAdapter<T> create(Gson gson, final TypeToken<T> type) { Class<? super T> raw = type.getRawType(); // 由上面的代码可知 这个是BaseJson类 但也是泛型类 if (!Object.class.isAssignableFrom(raw)) { // 根据程序走向 BaseJson 超类是Object return null; // it's a primitive! // 执行之后返回 ObjectConstructor<com.lifeon.watch.base.http.interceptor.BaseJson> ObjectConstructor<T> constructor = constructorConstructor.get(type); // 执行get()方法 return new Adapter<T>(constructor, getBoundFields(gson, type, raw)); // 这里将constructor 和 解析类对应的字段复制到Adapter中
ConstructorConstructor # get()
public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) { // com.lifeon.watch.base.http.interceptor.BaseJson<com.lifeon.watch.app.http.response.ResponseAppVersionInfo> final Type type = typeToken.getType(); // com.lifeon.watch.base.http.interceptor.BaseJson final Class<? super T> rawType = typeToken.getRawType(); @SuppressWarnings("unchecked") // types must agree final InstanceCreator<T> typeCreator = (InstanceCreator<T>) instanceCreators.get(type); // 集合中获取type类型的实例对象 if (typeCreator != null) { return new ObjectConstructor<T>() { // 根据type 创建一个对象的实例 @Override public T construct() { return typeCreator.createInstance(type); @SuppressWarnings("unchecked") // types must agree final InstanceCreator<T> rawTypeCreator = (InstanceCreator<T>) instanceCreators.get(rawType); // 集合中是否有rawType类型的实例 if (rawTypeCreator != null) { return new ObjectConstructor<T>() { @Override public T construct() { // 根据rawType 创建一个对象实例 return rawTypeCreator.createInstance(type); ObjectConstructor<T> defaultConstructor = newDefaultConstructor(rawType); // 创建一个默认的构造器 if (defaultConstructor != null) { return defaultConstructor; // 然后进行返回 ObjectConstructor<T> defaultImplementation = newDefaultImplementationConstructor(type, rawType); if (defaultImplementation != null) { return defaultImplementation; // finally try unsafe return newUnsafeAllocator(type, rawType);
ConstructorConstructor # newDefaultConstructor()
private <T> ObjectConstructor<T> newDefaultConstructor(Class<? super T> rawType) { try { final Constructor<? super T> constructor = rawType.getDeclaredConstructor(); if (!constructor.isAccessible()) { constructor.setAccessible(true); return new ObjectConstructor<T>() { @SuppressWarnings("unchecked") // T is the same raw type as is requested @Override public T construct() { try { Object[] args = null; return (T) constructor.newInstance(args); } catch (InstantiationException e) { // TODO: JsonParseException ? throw new RuntimeException("Failed to invoke " + constructor + " with no args", e); } catch (InvocationTargetException e) { // TODO: don't wrap if cause is unchecked! // TODO: JsonParseException ? throw new RuntimeException("Failed to invoke " + constructor + " with no args", e.getTargetException()); } catch (IllegalAccessException e) { throw new AssertionError(e); } catch (NoSuchMethodException e) { return null;
BaseJson 源代码
public class BaseJson<T> { private int code; private String message; private T data; public int getCode() { return code; public void setCode(int code) { this.code = code; public String getMessage() { return message; public void setMessage(String message) { this.message = message; public T getData() { return data; public void setData(T data) { this.data = data; @Override public String toString() { return "BaseJson{" + "code=" + code + ", message='" + message + '\'' + ", data=" + data + '}';
ReflectiveTypeAdapterFactory # getBoundFields()
private Map<String, BoundField> getBoundFields(Gson context, TypeToken<?> type, Class<?> raw) { Map<String, BoundField> result = new LinkedHashMap<String, BoundField>(); // 创建LinkedHashMap if (raw.isInterface()) { // 判断rawType是否是接口类 false return result; Type declaredType = type.getType(); // 拿到type类型 while (raw != Object.class) { // rawType非Object类型 Field[] fields = raw.getDeclaredFields(); // 获取BaseJson中所有字段 三个 for (Field field : fields) { boolean serialize = excludeField(field, true); // 使用排除器 是否排除当前字段得到结果 可序列化 boolean deserialize = excludeField(field, false); // 可反序列化 if (!serialize && !deserialize) { // 序列化和反序列化均不行 不管当前字段 进行下一个字段的执行 continue; field.setAccessible(true); // 设置字段的权限 Type fieldType = $Gson$Types.resolve(type.getType(), raw, field.getGenericType()); // 获取当前字段的类型 List<String> fieldNames = getFieldNames(field); // 获取当前字段的名称 BoundField previous = null; for (int i = 0, size = fieldNames. size(); i < size; ++i) { String name = fieldNames.get(i); if (i != 0) serialize = false; // only serialize the default name 只进行序列化默认第一个名称 BoundField boundField = createBoundField(context, field, name, TypeToken.get(fieldType), serialize, deserialize); // 实例化BoundField对象 BoundField replaced = result.put(name, boundField); // 将字段和boundField放入到链表hasp表中 if (previous == null) previous = replaced; // 如果前一个字段boundField为null 进行赋值 if (previous != null) { // 声明了多个名为name的字段 throw new IllegalArgumentException(declaredType + " declares multiple JSON fields named " + previous.name); type = TypeToken.get($Gson$Types.resolve(type.getType(), raw, raw.getGenericSuperclass())); raw = type.getRawType(); return result;
#### ReflectiveTypeAdapterFactory # createBoundField()
private ReflectiveTypeAdapterFactory.BoundField createBoundField( final Gson context, final Field field, final String name, final TypeToken<?> fieldType, boolean serialize, boolean deserialize) { final boolean isPrimitive = Primitives.isPrimitive(fieldType.getRawType()); // 判断是否是八大基础类型 + void类型 // special casing primitives here saves ~5% on Android... JsonAdapter annotation = field.getAnnotation(JsonAdapter.class); // 获取字段上面的json解析注解 TypeAdapter<?> mapped = null; if (annotation != null) { // 注解不为空的情况 开始解析注解 我们没有注解 是不管 mapped = jsonAdapterFactory.getTypeAdapter( constructorConstructor, context, fieldType, annotation); final boolean jsonAdapterPresent = mapped != null; if (mapped == null) mapped = context.getAdapter(fieldType); final TypeAdapter<?> typeAdapter = mapped; // 拿到对应的TypeAdapter // 实例化一个当前字段类型对应的BoundField对象 return new ReflectiveTypeAdapterFactory.BoundField(name, serialize, deserialize) { @SuppressWarnings({"unchecked", "rawtypes"}) // the type adapter and field type always agree @Override void write(JsonWriter writer, Object value) throws IOException, IllegalAccessException { Object fieldValue = field.get(value); TypeAdapter t = jsonAdapterPresent ? typeAdapter : new TypeAdapterRuntimeTypeWrapper(context, typeAdapter, fieldType.getType()); t.write(writer, fieldValue); @Override void read(JsonReader reader, Object value) throws IOException, IllegalAccessException { // 在下面的时候会进行解析到这里 Object fieldValue = typeAdapter.read(reader); if (fieldValue != null || !isPrimitive) { field.set(value, fieldValue); @Override public boolean writeField(Object value) throws IOException, IllegalAccessException { if (!serialized) return false; Object fieldValue = field.get(value); return fieldValue != value; // avoid recursion for example for Throwable.cause
没有注解的情况 调用到Gson.getAdapter(); (之前有做过解析) -----根据字段类型 获取符合条件的TypeAdapter
Adapter(ObjectConstructor<T> constructor, Map<String, BoundField> boundFields) { this.constructor = constructor; this.boundFields = boundFields;
接着上面json解析的过程 下面应该执行
T instance = constructor.construct();
由上面代码的分析 可以知道 会执行这个方法。
@Override public T construct() { try { Object[] args = null; return (T) constructor.newInstance(args); // 对拿到的解析类进行实例化操作 } catch ( InstantiationException e) { // TODO: JsonParseException ? throw new RuntimeException("Failed to invoke " + constructor + " with no args", e); } catch (InvocationTargetException e) { // TODO: don't wrap if cause is unchecked! // TODO: JsonParseException ? throw new RuntimeException("Failed to invoke " + constructor + " with no args", e.getTargetException()); } catch (IllegalAccessException e) { throw new AssertionError(e);
JsonReader # beginObject()
public void beginObject() throws IOException { int p = peeked; if (p == PEEKED_NONE) { // 上面代码执行之后是PEEKED_BEGIN_OBJECT p = doPeek(); if (p == PEEKED_BEGIN_OBJECT) { // 进入当前方法 push(JsonScope.EMPTY_OBJECT); peeked = PEEKED_NONE; } else { throw new IllegalStateException("Expected BEGIN_OBJECT but was " + peek() + locationString()); private void push(int newTop) { if (stackSize == stack.length) { // 如果stackSize=32 开始进行扩容处理 int[] newStack = new int[stackSize * 2]; int[] newPathIndices = new int[stackSize * 2]; String[] newPathNames = new String[stackSize * 2]; System.arraycopy(stack, 0, newStack, 0, stackSize); System.arraycopy(pathIndices, 0, newPathIndices, 0, stackSize); System.arraycopy(pathNames, 0, newPathNames, 0, stackSize); stack = newStack; pathIndices = newPathIndices; pathNames = newPathNames; stack[stackSize++] = newTop; // 按照上面的代码 可知 stackSize = 1 所以在下标为1的位置设置 EMPTY_OBJECT
ReflectiveTypeAdapterFactory开始执行是否有下一个 in.hasNext();
public boolean hasNext() throws IOException { int p = peeked; if (p == PEEKED_NONE) { // 由beginObject方法可知 判断正确 进入if p = doPeek(); // 第一次执行拿到 PEEKED_DOUBLE_QUOTED_NAME pos值为2 return p != PEEKED_END_OBJECT && p != PEEKED_END_ARRAY; // 返回 true
in.nextName(); 获取下一个名字 JsonReader # nextName();
public String nextName() throws IOException { int p = peeked; if (p == PEEKED_NONE) { p = doPeek(); String result; if (p == PEEKED_UNQUOTED_NAME) { // 如果上一个字符是无引号 result = nextUnquotedValue(); } else if (p == PEEKED_SINGLE_QUOTED_NAME) { // 如果上一个字符是单引号 result = nextQuotedValue('\''); } else if (p == PEEKED_DOUBLE_QUOTED_NAME) { // 如果上一个字符是双引号 result = nextQuotedValue('"'); // 获取当前双引号之间的数据信息 } else { throw new IllegalStateException("Expected a name but was " + peek() + locationString()); peeked = PEEKED_NONE; pathNames[stackSize - 1] = result; return result;
JsonReader # nextQuotedValue(’"’) json = {“username”:“hello”,“age”:18}
private String nextQuotedValue(char quote) throws IOException { // Like nextNonWhitespace, this uses locals 'p' and 'l' to save inner-loop field access. char[] buffer = this.buffer; StringBuilder builder = null; while (true) { int p = pos; // 根据上面的解析流程 这个pos = 2 int l = limit; /* the index of the first character not yet appended to the builder. */ int start = p; while (p < l) { int c = buffer[p++]; // buffer[2] = "u" if (c == quote) { // 拿取到下一个字符为双引号 pos = p; int len = p - start - 1; // 计算字符的长度 if (builder == null) { return new String(buffer, start, len); // 创建String对象 空字符 } else { builder.append(buffer, start, len); return builder.toString(); // 将拿到的数据进行返回 } else if (c == '\\') { // 出现转义符 pos = p; int len = p - start - 1; if (builder == null) { int estimatedLength = (len + 1) * 2; builder = new StringBuilder(Math.max(estimatedLength, 16)); builder.append(buffer, start, len); builder.append(readEscapeCharacter()); p = pos; l = limit; start = p; } else if (c == '\n') { // 出现换行 不进行处理 包含在String字符内 lineNumber++; lineStart = p; if (builder == null) { int estimatedLength = (p - start) * 2; // 初始化处理 --因为上面的情况我们都没有 这里的 p=3 start=2 estimatedLength=2 builder = new StringBuilder(Math.max(estimatedLength, 16)); // 初始化StringBuilder容量 为16 // 如果append之后的数值大于16 就会进行扩容处理 按照现在value.length * 2 + 2 进行扩容 // 将符合要求的buffer数据添加到builder中 从buffer中拿取数据 从start位置开始拿 拿取p-start个字符 builder.append(buffer, start, p - start); pos = p; // 对读取到什么位置进行赋值 因为上面的p++获取的数据 所以这里是 11 if (!fillBuffer(1)) { throw syntaxError("Unterminated string");
拿到name之后开始获取name对应的value值 in.skipValue()
JsonReader # skipValue()
public void skipValue() throws IOException { int count = 0; do { int p = peeked; if (p == PEEKED_NONE) { // 上面的name获取完成 重新置为NONE pos = 11 (根据示例json进行解析查看情况的) p = doPeek(); // 下一个符号是冒号 : peekStack = DANGLING_NAME 进行处理 拿到双引号 返回 PEEKED_DOUBLE_QUOTED if (p == PEEKED_BEGIN_ARRAY) { push(JsonScope.EMPTY_ARRAY); count++; } else if (p == PEEKED_BEGIN_OBJECT) { push(JsonScope.EMPTY_OBJECT); count++; } else if (p == PEEKED_END_ARRAY) { stackSize--; count--; } else if (p == PEEKED_END_OBJECT) { stackSize--; count--; } else if (p == PEEKED_UNQUOTED_NAME || p == PEEKED_UNQUOTED) { skipUnquotedValue(); } else if (p == PEEKED_SINGLE_QUOTED || p == PEEKED_SINGLE_QUOTED_NAME) { skipQuotedValue('\''); } else if (p == PEEKED_DOUBLE_QUOTED || p == PEEKED_DOUBLE_QUOTED_NAME) { skipQuotedValue('"'); // 进入到这个方法之前执性了两次获取下一个字符 这里得到的 pos = 13 } else if (p == PEEKED_NUMBER) { pos += peekedNumberLength; peeked = PEEKED_NONE; } while (count != 0); pathIndices[stackSize - 1]++; pathNames[stackSize - 1] = "null";
JsonReader # skipQuotedValue()
private void skipQuotedValue(char quote) throws IOException { // Like nextNonWhitespace, this uses locals 'p' and 'l' to save inner-loop field access. char[] buffer = this.buffer; do { int p = pos; // 13 int l = limit; // 29 /* the index of the first character not yet appended to the builder. */ while (p < l) { int c = buffer[p++]; // 第一次遍历 拿到是[13]= 'h' if (c == quote) { // 拿到下一个 " 直接返回 pos = p; // 因为上面的示例代码是有双引号的 即 pos = 19 return; } else if (c == '\\') { pos = p; readEscapeCharacter(); p = pos; l = limit; } else if (c == '\n') { // 遍历到换行符 lineNumber++; // 进行 +1 操作 lineStart = p; // 行开始位置 pos = p; } while (fillBuffer(1)); throw syntaxError("Unterminated string");
如果执行skipValue,pos = 19; 不执行的话 目前没有跳过 pos = 11
下面看执行read操作
field.read(in, instance);
new ReflectiveTypeAdapterFactory.BoundField
@Override void read(JsonReader reader, Object value) throws IOException, IllegalAccessException { // 在下面的时候会进行解析到这里 Object fieldValue = typeAdapter.read(reader); // 因为上面解析的是String类型 对应的也是String 执行这个的读取操作 if (fieldValue != null || !isPrimitive) { // 拿到filedValue = "hello" 不为null field.set(value, fieldValue); // 执行set方法 将value值和对应的实例 保存到字段信息中
TypeAdapters # STRING 中进行执行read操作 因为原有的项目json字符串比较长 所以还是按照上面json进行解析
public static final TypeAdapter<String> STRING = new TypeAdapter<String>() { @Override public String read(JsonReader in) throws IOException { // 进入到peek方法中拿到 peek 这里的pos = 11 下一个符号是冒号 : peekStack = DANGLING_NAME 进行处理 拿到双引号 返回 PEEKED_DOUBLE_QUOTED JsonToken peek = in.peek(); // 拿到JsonToken JsonToken.STRING if (peek == JsonToken.NULL) { // 空 in.nextNull(); return null; /* coerce booleans to strings for backwards compatibility */ if (peek == JsonToken.BOOLEAN) { // boolean处理 return Boolean.toString(in.nextBoolean()); return in.nextString(); // 获取下一个String @Override public void write(JsonWriter out, String value) throws IOException { out.value(value);
in.nextString(); JsonReader # nextString();
public String nextString() throws IOException { // peeked = PEEKED_DOUBLE_QUOTED int p = peeked; if (p == PEEKED_NONE) { p = doPeek(); String result; if (p == PEEKED_UNQUOTED) { result = nextUnquotedValue(); } else if (p == PEEKED_SINGLE_QUOTED) { result = nextQuotedValue('\''); } else if (p == PEEKED_DOUBLE_QUOTED) { // 双引号进入到这个方法进行执行 result = nextQuotedValue('"'); // 获取到下一个双引号的位置 并且返回这之间的所有数据 "hello" 上面有进行这个方法的解析过程 } else if (p == PEEKED_BUFFERED) { result = peekedString; peekedString = null; } else if (p == PEEKED_LONG) { result = Long.toString(peekedLong); } else if (p == PEEKED_NUMBER) { result = new String(buffer, pos, peekedNumberLength); pos += peekedNumberLength; } else { throw new IllegalStateException("Expected a string but was " + peek() + locationString()); peeked = PEEKED_NONE; pathIndices[stackSize - 1]++; return result;
第一个json字段的对应的name和value数据都拿到,下一步判断是否还有下一步
while (in.hasNext()) {}
// 根据上面拿到value值 pos = 19 peeked = PEEKED_NONE stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT
进入hasNext()之后
stack[stackSize - 1] = JsonScope.DANGLING_NAME
根据上面代码得知 in.hasNext() = true; pos = 21 peeked = PEEKED_DOUBLE_QUOTED_NAME
对此持续循环解析,拿到in.nextName= “age”; pos = 25 peeked = PEEKED_NONE
之后判断承载对象的类中是否有这个字段,有,进行int解析,没有,跳过当前值TypeAdapters # INTEGER field.read()
public static final TypeAdapter<Number> INTEGER = new TypeAdapter<Number>() { @Override public Number read(JsonReader in) throws IOException { if (in.peek() == JsonToken.NULL) { in.nextNull(); return null; try { return in.nextInt(); // 开始进行数值解析 } catch (NumberFormatException e) { throw new JsonSyntaxException(e); @Override public void write(JsonWriter out, Number value) throws IOException { out.value(value);
JsonReader # nextInt() 获取
public int nextInt() throws IOException { int p = peeked; if (p == PEEKED_NONE) { // stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT; p = doPeek(); // 先拿到 : 不管 pos = 26 ‘1’ pos = 27 会执行 pos-- 所以 pos= 26 检查是否是关键字 false 检查是否是number true // value = 18 peek = PEEKED_LONG int result; if (p == PEEKED_LONG) { // 进入当前判断 result = (int) peekedLong; // peekedLong = 18 peekNumber方法中进行赋值 if (peekedLong != result) { // Make sure no precision was lost casting to 'int'. 确保没有精度损失到int throw new NumberFormatException("Expected an int but was " + peekedLong + locationString()); peeked = PEEKED_NONE; pathIndices[stackSize - 1]++; return result; if (p == PEEKED_NUMBER) { peekedString = new String(buffer, pos, peekedNumberLength); pos += peekedNumberLength; } else if (p == PEEKED_SINGLE_QUOTED || p == PEEKED_DOUBLE_QUOTED || p == PEEKED_UNQUOTED) { if (p == PEEKED_UNQUOTED) { peekedString = nextUnquotedValue(); } else { peekedString = nextQuotedValue(p == PEEKED_SINGLE_QUOTED ? '\'' : '"'); try { result = Integer.parseInt(peekedString); peeked = PEEKED_NONE; pathIndices[stackSize - 1]++; return result; } catch (NumberFormatException ignored) { // Fall back to parse as a double below. } else { throw new IllegalStateException("Expected an int but was " + peek() + locationString()); peeked = PEEKED_BUFFERED; double asDouble = Double.parseDouble(peekedString); // don't catch this NumberFormatException. result = (int) asDouble; if (result != asDouble) { // Make sure no precision was lost casting to 'int'. throw new NumberFormatException("Expected an int but was " + peekedString + locationString()); peekedString = null; peeked = PEEKED_NONE; pathIndices[stackSize - 1]++; return result;
执行结束之后
stack[stackSize - 1] = JsonScope.NONEMPTY_OBJECT
peeked = PEEKED_NONE
pos = 28
再进行执行 in.hasNext() 字符为 ‘}’
stack[stackSize - 1] = JsonScope.DANGLING_NAME;
peeked = PEEKED_END_OBJECT
pos = 29
hasNext() 执行之后返回false 表示没有下一个数据了 已经结束了
执行 in.endObject();
public void endObject() throws IOException { int p = peeked; if (p == PEEKED_NONE) { p = doPeek(); if (p == PEEKED_END_OBJECT) { // 回到初始化状态 等待下一次的分析进入 stackSize--; pathNames[stackSize] = null; // Free the last path name so that it can be garbage collected! pathIndices[stackSize - 1]++; peeked = PEEKED_NONE; } else { throw new IllegalStateException("Expected END_OBJECT but was " + peek() + locationString());
我们需要整理一下上面代码执行完之后重要参数的值目前是什么
pos = 29
peeked = PEEKED_NONE
因为stackSize-- 自减 根据之前的代码分析可以知道 stackSize = 2 endObject之后 stackObject = 1
那么 stack[stackSize - 1] = JsonScope.NONEMPTY_DOCUMENT; // 最开始的时候进行的赋值操作json数据就已经解析完了,并返回了一个实例类 instance ,代码开始回到调用convert的方法中
@Override public T convert(ResponseBody value) throws IOException { JsonReader jsonReader = gson.newJsonReader(value.charStream()); try { T result = adapter.read(jsonReader); // 上面已经拿到instance 的示例对象了 // 还有一次peek执行 查看是否已经结束 // buffer[p++] 得到的值为 -1 所以拿取的peek为END_DOCUMENT if (jsonReader.peek() != JsonToken.END_DOCUMENT) { throw new JsonIOException("JSON document was not fully consumed."); return result; // 解析成功将结果进行返回 } finally { value.close(); // 响应体进行关闭操作
再次回调到
OkHttpCall # parseResponse()方法中
return Response.success(body, rawResponse); // 返回成功的回调
OkHttpCall # execute() 直接将Response进行返回
CallObservable # subscribeActual()开始接着向下执行
@Override protected void subscribeActual(Observer<? super Response<T>> observer) { // Since Call is a one-shot type, clone it for each new observer. Call<T> call = originalCall.clone(); // 对原始的请求数据进行克隆 observer.onSubscribe(new CallDisposable(call)); // 开始执行onSubscribe方法 boolean terminated = false; try { Response<T> response = call.execute(); // 请求开始执行 会进行阻塞 拿到Response开始向下分发 if (!call.isCanceled()) { // 请求未被取消 拿到数据之后进行传递 执行onNext方法 observer.onNext(response); // 开始向下执行onNext()方法 if (!call.isCanceled()) { // 未被取消 则执行完成 如果没有出现其他问题 那么就执行onComplete() 整个流程执行完成 terminated = true; observer.onComplete(); } catch (Throwable t) { // 如果执行过程中出现异常 ,则直接执行onError Exceptions.throwIfFatal(t); if (terminated) { RxJavaPlugins.onError(t); // 执行异常方法 } else if (!call.isCanceled()) { try { observer.onError(t); } catch (Throwable inner) { Exceptions.throwIfFatal(inner); RxJavaPlugins.onError(new CompositeException(t, inner));// 执行异常方法
整个Retrofit的请求过程和解析过程就分析完了,整体来说有些绕,我都被绕了好几次走不出来。(▽)
Retrofit2.0原理解析目前的网络框架基本上都是使用Retrofit+okhttp一起进行使用,那么我们来看看retrofit究竟做了些什么。结合上一篇的OkHttp源码解析,在这个的基础上加上了Retrofit,下面是正常使用时候的代码。初始化Retrofit private void initRetrofit() { OkHttpClient client = new OkHttpClient.Builder() .addInter
下面是整个流程的流程图
如果有什么不对的,请多多指点。Caused by: java.lang.IllegalArgumentException: Expected URL scheme 'http' or 'https' but no colon was found at okhttp3.HttpUrl$Builder.parse(HttpUrl.java:1333) at okhttp3.HttpUrl.get(H...* Retrofit adapts a Java interface to HTTP calls by using annotations on the declared methods to * define how requests are made. Create instances using {@linkplain Builder * the builder} and pass your interface to {@link #create} to generate an implemen.1、Retrofit 实现原理 Retrofit 通过 java 接口以及注解来描述网络请求,并用动态代理的方式生成网络请求的 request,然后通过 client 调用相应的网络框架(默认 okhttp)去发起网络请求,并将返回的 response 通过 converterFactorty 转换成相应的数据 model,最后通过 calladapter 转换成其他数据方式(如 rxjava Observable) 通过 Retrofit. create( ciass)方法创建出 Service in紧接上文Android进阶:七、Retrofit2.0原理解析之最简流程【上】 一.请求参数整理 我们定义的接口已经被实现,但是我们还是不知道我们注解的请求方式,参数类型等是如何发起网络请求的呢? 这时我们可能应该关注一下ServiceMethod<Object, Object>对象的构建了: ServiceMethod<Object, Object> service...
![]() |
果断的可乐 · 金融风险的防范与法律制度的完善 5 月前 |