Android框架-Retrofit

转载

Retrofit 核心功能、关键节点

1、Retrofit # create() 动态代理:实现对不同业务的 APIService 聚合统一调用
2、CallAdapterFactory:请求适配工厂,比如,实现 RxJava 的支持 (RxJava2CallAdapter)
3、ConverterFactory:解析工厂,Response 数据解析,转为 JavaBean
4、callFactory:OkHttpClient 就是一个 callFactory的实现类,用于创建 RealCall 对象

执行流程

baseUrl
CallAdapterFactory
ConverterFactory请求结果数据转换
build 生成 Retrofit 对象
网络请求相关方法
缓存中没有该Method对应 ServiceMethod
缓存中已存在
同步请求
异步请求
Retrofit # Builder
Retrofit
定义请求API 接口 APIService
获取API实例 retrofit#create
传入 APIService.class
对API中所有方法实现动态代理
调用API实例方法
apiService # requestData
触发动态代理
调用 Retrofit # loadServiceMethod
传入 Method对象 获取 ServiceMethod
从缓存同步获取ServiceMethod
同步创建 ServiceMethod 后放入缓存
返回 ServiceMethod 实例
一个 ServiceMethod 对象 APIService 的一个方法
缓存目的 同一个 API 的同一个方法 只会创建一次
ServiceMethod
callFactory请求工厂 创建 Okhttp # RealCall 对象
callAdapter 请求适配器 对 RealCall的包装
responseConverter 数据解析
parameterHandlers 解析参数注解 获取参数信息
ServiceMethod # invoke 传入 方法参数
创建 retrofit2.OkHttpCall
调用 ServiceMethod # adapt 传入 OkHttpCall 和 参数
callAdapter.adapt
Retrofit#Builder 构建时传入
RxJava2CallAdapter 包装 RealCall 返回 Observable 对象
默认 DefaultCallAdapterFactory # CallAdapter
OkHttpCall # execute 同步请求
callFactory.newCall 创建 RealCall
Okhttp3 # Call # execute 执行 Okhttp 同步请求流程
OkHttpCall # parseResponse 解析 Response
OkHttpCall # enqueue 异步请求
callFactory.newCall 创建 RealCall
Okhttp3 # Call # enqueue 执行OkHttp 异步请求流程
responseConverter # convert 解析 RsponseBody 转为对象

一、使用

1、创建 Retrofit 对象
Retrofit retrofit = new Retrofit.Builder()
	.baseUrl("https://api.github.com/")
	.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
	.addConverterFactory(GsonConverterFactory.create())
	.build();
2、定义API 并获取 API 实例
public interface GitHubService {
	@GET("users/{user}/repos")
	Call<List<Repo>> listRepos(@Path("user") String user);
}
GitHubService github = retrofit.create(GitHubService.class);

二、Retrofit执行请求的整个流程

//1) 获取 API 实例
XXXService service = Retrofit.create(XXXService.class);

/* 2) 调用 API 实例的 某个网络请求方法
 *
 * 此时会触发 Retrofit#create()中动态代理的方法,依次执行以下三行代码
 *		
 *		ServiceMethod<Object, Object> serviceMethod = loadServiceMethod(method);
 *		retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
 *		return serviceMethod.adapt(okHttpCall);
 */
service.requestXXX(...);

//3)获取 ServiceMethod 对象,包含了请求的方法信息、参数信息、CallAdapter、ResponseAdapter、callFactory等
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);

//4)创建 OkHttpCall 对象,内部封装了同步/异步请求的实现
retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);

/* 5)调用 CallAdapter.adapt(okHttpCall)
 * 		
 *		不同的 CallAdapter 会有不同的实现,
 * 		  i. RxJava2CallAdapter.adapt()会把网络请求封装成一个 Observable<T> 对象返回。
 *			 这种方式是为了支持RxJava
 *			 
 *		  ii.DefaultCallAdapterFactory.adapt()会把 Call<T> 返回
 *			 这种方式是不需要支持RxJava的情况,拿到 Call 后,执行同步call.execute(),异步请求call.enqueue()
 */
serviceMethod.adapt(okHttpCall) -> CallAdapter.adapt()
1、获取 API 实例
public final class Retrofit {
	
	public <T> T create(final Class<T> service) {
		Utils.validateServiceInterface(service);
		if (validateEagerly) {
			eagerlyValidateMethods(service);
		}
		return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
			new InvocationHandler() {
				private final Platform platform = Platform.get();

				@Override 
				public Object invoke(Object proxy, Method method, @Nullable Object[] args) throws Throwable {
					//如果调用的是Object 的方法,则直接调用,使用代理
					if (method.getDeclaringClass() == Object.class) {
						return method.invoke(this, args);
					}
					//如果是 default 方法(Java 8 引入),就调用 default 方法
					if (platform.isDefaultMethod(method)) {
						return platform.invokeDefaultMethod(method, service, proxy, args);
					}
					ServiceMethod<Object, Object> serviceMethod = 
									(ServiceMethod<Object, Object>) loadServiceMethod(method);
					retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
					return serviceMethod.adapt(okHttpCall);
				}
			});
	}
}

关键代码:
	ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
	retrofit2.OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
	return serviceMethod.adapt(okHttpCall);
2、获取 ServiceMethod
ServiceMethod 中 包含有各个工厂的实例。

// Retrofit#loadServiceMethod()

ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);

(1) ServiceMethod<T> 把接口方法的调用转为一次 HTTP 调用
一个 ServiceMethod 对象对应于一个 API interface 的一个方法
loadServiceMethod(method) 方法负责加载 ServiceMethod。

ServiceMethod loadServiceMethod(Method method) {
	ServiceMethod result;
	synchronized (serviceMethodCache) {
		result = serviceMethodCache.get(method);
		if (result == null) {
			result = new ServiceMethod.Builder(this, method).build();
			serviceMethodCache.put(method, result);
		}
	}
	return result;
}

实现了缓存逻辑,同一个 API 的同一个方法,只会创建一次。
我们每次获取 API 实例都是传入的 class 对象,而 class 对象是进程内单例的,
所以获取到它的同一个方法 Method 实例也是单例的,所以这里的缓存是有效的

final class ServiceMethod<R, T> {
	private final okhttp3.Call.Factory callFactory;
	private final CallAdapter<R, T> callAdapter;
	private final Converter<ResponseBody, R> responseConverter;
	private final ParameterHandler<?>[] parameterHandlers;
	...

	ServiceMethod(Builder<R, T> builder) {
		this.callFactory = builder.retrofit.callFactory();
		this.callAdapter = builder.callAdapter;
		this.responseConverter = builder.responseConverter;
		this.parameterHandlers = builder.parameterHandlers;
		...			
	}
}
  • 1)okhttp3.Call.Factory callFactory 请求工厂

    负责创建 HTTP 请求,HTTP 请求被抽象为了 okhttp3.Call 类,
    它表示一个已经准备好,可以随时执行的 HTTP 请求;
    OkHttpClient 实现了这个接口。

    在构造Retrofit 对象时,可以指定 callFactory,如果不指定,将默认设置为一个 okhttp3.OkHttpClient

  • 2)CallAdapter<R, T> callAdapter 请求适配器
    把 retrofit2.Call 转为 T。

    (注意和 okhttp3.Call 区分开来,retrofit2.Call 表示的是对一个 Retrofit 方法的调用),
    这个过程会发送一个 HTTP 请求,拿到服务器返回的数据(通过 okhttp3.Call 实现),
    并把数据转换为声明的 T 类型对象(通过 Converter<F, T> 实现);

      final class ServiceMethod<R, T> {		   
      	private CallAdapter<T, R> createCallAdapter() {
      		Type returnType = method.getGenericReturnType();
      		// 省略检查性代码
      		...				
      		Annotation[] annotations = method.getAnnotations();
      		try {
      			return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
      		} catch (RuntimeException e) { // Wide exception range because factories are user code.
      			throw methodError(e, "Unable to create call adapter for %s", returnType);
      		}
      	}
      }
      
      public final class Retrofit {
      	/* 这个工厂列表我们可以在构造 Retrofit 对象时进行添加
      	 * Retrofit retrofit = new Retrofit.Builder()
      			.baseUrl("https://api.github.com/")
      			.addCallAdapterFactory()
      			.build()
      	 */
      	final List<CallAdapter.Factory> callAdapterFactories;
      	
      	public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
      		return nextCallAdapter(null, returnType, annotations);
      	}
    
      	/**
      	 * 遍历一个 CallAdapter.Factory 列表,让工厂们提供,
      	 * 如果最终没有工厂能(根据 returnType 和 annotations)提供需要的 CallAdapter,那将抛出异常。
      	 */
      	public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      		  Annotation[] annotations) {
      		...
      		int start = callAdapterFactories.indexOf(skipPast) + 1;
      		for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      			CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      			if (adapter != null) {
      				return adapter;
      			}
      		}
      		...
      		throw new IllegalArgumentException(...);
      	}
      }
    
  • 3)responseConverter 是 Converter<ResponseBody, T> 类型,
    负责把服务器返回的数据(JSON、XML、二进制或者其他格式,由 ResponseBody 封装)转化为 T 类型的对象;

      final class ServiceMethod<R, T> {
      	
      	private Converter<ResponseBody, T> createResponseConverter() {
      		Annotation[] annotations = method.getAnnotations();
      		try {
      			return retrofit.responseBodyConverter(responseType, annotations);
      		} catch (RuntimeException e) { // Wide exception range because factories are user code.
      			throw methodError(e, "Unable to create converter for %s", responseType);
      		}
      	}
      }
      	
      public final class Retrofit {
      	/* 这个工厂列表我们可以在构造 Retrofit 对象时进行添加
      	 *
      		Retrofit retrofit = new Retrofit.Builder()
      			.addConverterFactory(GsonConverterFactory.create())
      			.build();
      	 */
      	final List<Converter.Factory> converterFactories;
      	
      	public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
      		return nextResponseBodyConverter(null, type, annotations);
      	}
    
         /**
      	* 遍历 Converter.Factory 列表,看看有没有工厂能够提供需要的 responseBodyConverter。
      	* 工厂列表可以在构造 Retrofit 对象时进行添加。
      	*/
      	public <T> Converter<ResponseBody, T> nextResponseBodyConverter(@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
      		...
      		int start = converterFactories.indexOf(skipPast) + 1;
      		for (int i = start, count = converterFactories.size(); i < count; i++) {
      			Converter<ResponseBody, ?> converter =
      				  converterFactories.get(i).responseBodyConverter(type, annotations, this);
      			if (converter != null) {
      				return (Converter<ResponseBody, T>) converter;
      			}
      		}
      		...
      		throw new IllegalArgumentException(...);
      	}
      }
    
  • 4)parameterHandlers 则负责解析 API 定义时每个方法的参数,并在构造 HTTP 请求时设置参数;

    i.每个参数都会有一个 ParameterHandler,由 ServiceMethod#parseParameter() 方法负责创建
    每个参数的信息解析出来后都会包装成一个 ParameterHandler 对象。

    ii.ServiceMethod#parseParameter()
    其主要内容就是解析每个参数使用的注解类型(诸如 Path,Query,Field 等),
    对每种类型进行单独的处理。

    构造 HTTP 请求时,我们传递的参数都是字符串,
    那 Retrofit 是如何把我们传递的各种参数都转化为 String 的呢?
    还是由 Retrofit 类提供 converter!

    Converter.Factory 除了提供上一小节提到的 responseBodyConverter,
    还提供 requestBodyConverter 和 stringConverter,API 方法中除了 @Body 和 @Part 类型的参数,
    都利用 stringConverter 进行转换,
    而 @Body 和 @Part 类型的参数则利用 requestBodyConverter 进行转换。

    这三种 converter 都是通过“询问”工厂列表进行提供,
    而工厂列表我们可以在构造 Retrofit 对象时进行添加。

    (2)工厂让各个模块得以高度解耦

    各个工厂负责不同的功能,而Retrofit 值负责向工厂提供用于决策的信息,例如参数/返回值类型/注解等。

3、创建 retrofit2.OkHttpCall

OkHttpCall内部封装了 同步/异步网络请求

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

OkHttpCall 实现了 retrofit2.Call,我们通常会使用它的 execute() 和 enqueue(Callback callback) 接口。
前者用于同步执行 HTTP 请求,后者用于异步执行。

final class OkHttpCall<T> implements Call<T> {
	//1)同步请求
	@Override 
	public Response<T> execute() throws IOException {
		okhttp3.Call call;
		synchronized (this) {
			//【1】创建 okhttp3.Call,包括构造参数;
			call = rawCall;
			if (call == null) {
				try {
					call = rawCall = createRawCall();
				} catch (IOException | RuntimeException e) {
					creationFailure = e;
					throw e;
				}
			}
		}
		//【2】call.execute() 同步执行网络请求,返回 Response 对象
		//【3】解析网络请求返回的数据;
		return parseResponse(call.execute());
	}
	// callFactory 就是 OkHttpClient
	private okhttp3.Call createRawCall() throws IOException {
		Request request = serviceMethod.toRequest(args);
		okhttp3.Call call = serviceMethod.callFactory.newCall(request);
		if (call == null) {
			throw new NullPointerException("Call.Factory returned null.");
		}
		return call;
	}
	
	//解析网络请求返回的数据
	Response<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) {
			// ...返回错误
		}

		if (code == 204 || code == 205) {
			return Response.success(null, rawResponse);
		}

		ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
		try {
			// 内部调用 responseConverter.convert(body) 把body 转成 T
			T body = serviceMethod.toResponse(catchingBody);
			return Response.success(body, rawResponse);
		} catch (RuntimeException e) {
			// ...异常处理
		}
	}
	
	//2)异步请求
	@Override 
	public void enqueue(final Callback<T> callback) {
		...
		okhttp3.Call call;
		Throwable failure;
		synchronized (this) {
			if (executed) throw new IllegalStateException("Already executed.");
			executed = true;
			//【1】创建 okhttp3.Call,包括构造参数;
			call = rawCall;
			failure = creationFailure;
			if (call == null && failure == null) {
				try {
					call = rawCall = createRawCall();
				} catch (Throwable t) {
					throwIfFatal(t);
					failure = creationFailure = t;
				}
			}
		}
		if (failure != null) {
			callback.onFailure(this, failure);
			return;
		}
		if (canceled) {
			call.cancel();
		}
		//【2】调用 okhttp3.Call 的 enqueue() 方法,执行异步请求
		call.enqueue(new okhttp3.Callback() {
			
			@Override 
			public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
				Response<T> response;
				try {
					//【3】解析响应数据
					response = parseResponse(rawResponse);
				} catch (Throwable e) {
					callFailure(e);
					return;
				}
				try {
					callback.onResponse(OkHttpCall.this, response);
				} catch (Throwable t) {
					t.printStackTrace();
				}
			}
			...
		});
	}
}
4、CallAdapter.adapt(okHttpCall) //请求适配器适配
serviceMethod.adapt(okHttpCall);

内部调用的是  CallAdapter.adapt(call) 方法

final class ServiceMethod<R, T> {
	
	T adapt(Call<R> call) {
		return callAdapter.adapt(call);
	}
}

CallAdapter#adapt(Call call) 函数负责把 retrofit2.Call 转为 T。
这里 T 当然可以就是 retrofit2.Call,这时我们直接返回参数就可以了,
实际上这正是 DefaultCallAdapterFactory 创建的 CallAdapter 的行为。
至于其他类型的工厂返回的 CallAdapter 的行为,这里暂且不表,后面再单独分析。

三、retrofit-adapters 模块

Retrofit中 CallAdapter 的适配器模式

retrofit 模块内置了 DefaultCallAdapterFactory 和 ExecutorCallAdapterFactory,
它们都适用于 API 方法得到的类型为 retrofit2.Call 的情形,

  • 1)DefaultCallAdapterFactory 生产的 adapter 啥也不做,直接把参数返回,

  • 2)ExecutorCallAdapterFactory 生产的 adapter 则会在异步调用时在指定的 Executor 上执行回调。

    异步请求结束后,会在 callbackExecutor 回调结果
    ExecutorCallAdapterFactory(Executor callbackExecutor)

  • 3)RxJavaCallAdapterFactory

    RxJava2CallAdapterFactory#get 方法中对返回值的类型进行了检查,
    只支持 rx.Single,rx.Flowable,rx.Maybe,rx.Completable 和 rx.Observable,
    然后返回 RxJava2CallAdapter 对象。

    如果 Retrofit 中设置了 RxJavaCallAdapterFactory,那么 Retrofit的 CallAdapter 就是 RxJava2CallAdapter

    RxJava2CallAdapter.adapt() 会返回一个 Obserable对象。
    Observable.subscribe,触发 API 调用的执行;

    final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
      	
      	@Override 
      	public Object adapt(Call<R> call) {
      		Observable<Response<R>> responseObservable = isAsync
      			//异步请求,创建  CallEnqueueObservable
      			? new CallEnqueueObservable<>(call)
      			//同步请求,创建 CallExecuteObservable
      			: new CallExecuteObservable<>(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;
      	  }			
      }
    

执行网络请求时,会调用 ServiceMethod.adapt() -> RxJava2CallAdapter.adapt()

i.异步请求 CallEnqueueObservable

final class CallEnqueueObservable<T> extends Observable<Response<T>> {
	private final Call<T> originalCall;

	CallEnqueueObservable(Call<T> originalCall) {
		this.originalCall = originalCall;
	}

	@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();
		CallCallback<T> callback = new CallCallback<>(call, observer);
		
		/*
		 * observer在 callback构造函数中已经把 observer传入,并且在 callback的对应函数中做了回调
		 * 调用observer#onSubscribe(@NonNull Disposable d)方法,通知应用层要开始请求了
		 */
		observer.onSubscribe(callback);
		call.enqueue(callback);
	}

	private static final class CallCallback<T> implements Disposable, Callback<T> {
		private final Call<?> call;
		private final Observer<? super Response<T>> observer;
		private volatile boolean disposed;
		boolean terminated = false;

		CallCallback(Call<?> call, Observer<? super Response<T>> observer) {
			this.call = call;
			this.observer = observer;
		}

		@Override
		public void onResponse(Call<T> call, Response<T> response) {
			...
			observer.onNext(response);
			...
			observer.onComplete();
			...
			observer.onError(t);
		}

		@Override 
		public void onFailure(Call<T> call, Throwable t) {
			...
			observer.onError(t);
			...
		}
		...
	}
}

ii.同步请求 CallExecuteObservable

final class CallExecuteObservable<T> extends Observable<Response<T>> {
	private final Call<T> originalCall;

	CallExecuteObservable(Call<T> originalCall) {
		this.originalCall = originalCall;
	}

	@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();
		CallDisposable disposable = new CallDisposable(call);
		observer.onSubscribe(disposable);

		boolean terminated = false;
		try {
			//调用 retrofit.OkHttpCall.execute()会调用 OkHttp.Call.execute()执行同步请求
			Response<T> response = call.execute();
			if (!disposable.isDisposed()) {
				observer.onNext(response);
			}
			if (!disposable.isDisposed()) {
				terminated = true;
				observer.onComplete();
			}
		} catch (Throwable t) {
			Exceptions.throwIfFatal(t);
			if (terminated) {
				RxJavaPlugins.onError(t);
			} else if (!disposable.isDisposed()) {
				try {
					observer.onError(t);
				} catch (Throwable inner) {
					Exceptions.throwIfFatal(inner);
					RxJavaPlugins.onError(new CompositeException(t, inner));
				}
			}
		}
	}

	private static final class CallDisposable implements Disposable {
		private final Call<?> call;
		private volatile boolean disposed;

		CallDisposable(Call<?> call) {
			this.call = call;
		}

		@Override public void dispose() {
			disposed = true;
			call.cancel();
		}

		@Override public boolean isDisposed() {
			return disposed;
		}
	}
}

四、retrofit-converters 模块

GsonConverterFactory 把网络请求返回的 Response 转成 T 对象

public final class GsonConverterFactory extends Converter.Factory {
	@Override
	public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
		TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
		return new GsonResponseBodyConverter<>(gson, adapter);
	}
}	

final class GsonResponseBodyConverter<T> implements Converter<ResponseBody, T> {
	private final Gson gson;
	private final TypeAdapter<T> adapter;

	GsonResponseBodyConverter(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());
		try {
			T result = adapter.read(jsonReader);
			if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
				throw new JsonIOException("JSON document was not fully consumed.");
			}
			return result;
		} finally {
			value.close();
		}
	}
}

五、Retrofit中 ConverterFactory、CallAdapterFactory 的理解

工厂模式,方便使用者根据需要自定义实现对应功能

六、Gson解析异常数据处理

public class JsonUtil {

	public static Gson getGson() {
		return new GsonBuilder()
				.serializeNulls()
				.registerTypeAdapterFactory(new NullTypeToEmptyAdapterFactory())
				.create();
	}
}

Retrofit创建时调用:

	Retrofit retrofit = new Retrofit.Builder()
		.baseUrl("https://api.github.com/")
		.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
		.addConverterFactory(GsonConverterFactory.create(JsonUtil.getGson()))
		.build();

/**
 * Json数据适配器
 */
public class NullTypeToEmptyAdapterFactory implements TypeAdapterFactory {

	@Override
	public <T> TypeAdapter<T> create (Gson gson, TypeToken<T> type) {
		Class<T> rawType = (Class<T>) type.getRawType();
		if (rawType == String.class) {
			return (TypeAdapter<T>) new StringNullAdapter();
		} else if (rawType == Integer.class) {
			return (TypeAdapter<T>) new IntegerNullAdapter();
		} else if (rawType == Double.class) {
			return (TypeAdapter<T>) new DoubleNullAdapter();
		} else if (rawType == Float.class) {
			return (TypeAdapter<T>) new FloatNullAdapter();
		} else if (rawType == Long.class) {
			return (TypeAdapter<T>) new LongNullAdapter();
		}
		return null;
	}

	class StringNullAdapter extends TypeAdapter<String> {

		@Override
		public String read (JsonReader reader) throws IOException {
			String str = "";
			if (reader.peek() == JsonToken.NULL) {
				reader.nextNull();
				return str;
			}
			try {
				str = reader.nextString();
			} catch (Exception e) {
				str = JsonUtil.getGson().toJson(new JsonParser().parse(reader));
			}
			return str;
		}

		@Override
		public void write (JsonWriter writer, String value) throws IOException {
//            if (value == null) {
//                writer.nullValue();
//                return;
//            }
			writer.value(value);
		}
	}

	class IntegerNullAdapter extends TypeAdapter<Integer> {

		@Override
		public void write (JsonWriter out, Integer value) throws IOException {
			out.value(value);
		}

		@Override
		public Integer read (JsonReader in) throws IOException {
			if (in.peek() == JsonToken.NULL) {
				in.nextNull();
				return 0;
			}
			return in.nextInt();
		}
	}

	class DoubleNullAdapter extends TypeAdapter<Double> {

		@Override
		public void write (JsonWriter out, Double value) throws IOException {
			out.value(value);
		}

		@Override
		public Double read (JsonReader in) throws IOException {
			if (in.peek() == JsonToken.NULL) {
				in.nextNull();
				return 0.0;
			}
			return in.nextDouble();
		}
	}

	class LongNullAdapter extends TypeAdapter<Long> {

		@Override
		public void write (JsonWriter out, Long value) throws IOException {
			out.value(value);
		}

		@Override
		public Long read (JsonReader in) throws IOException {
			if (in.peek() == JsonToken.NULL) {
				in.nextNull();
				return 0L;
			}
			return in.nextLong();
		}
	}

	class FloatNullAdapter extends TypeAdapter<Float> {

		@Override
		public void write (JsonWriter out, Float value) throws IOException {
			out.value(value);
		}

		@Override
		public Float read (JsonReader in) throws IOException {
			if (in.peek() == JsonToken.NULL) {
				in.nextNull();
				return 0f;
			}
			return Float.parseFloat(String.valueOf(in.nextDouble()));
		}
	}
}

推荐阅读:
拆轮子系列:拆Retrofit https://blog.piasy.com/2016/06/25/Understand-Retrofit/index.html

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值