http://apis.juhe.cn/simpleWeather/query?key=**
//key可以到聚合数据申请
/**
* reason : 查询成功!
* result : {“city”:“武汉”,“realtime”:{“temperature”:“28”,“humidity”:“82”,“info”:“阴”,“wid”:“02”,“direct”:“东北风”,“power”:“1级”,“aqi”:“35”},“future”:[{“date”:“2020-07-17”,“temperature”:“24/32℃”,“weather”:“小雨转中雨”,“wid”:{“day”:“07”,“night”:“08”},“direct”:“西南风转东北风”},{“date”:“2020-07-18”,“temperature”:“23/32℃”,“weather”:“小雨转暴雨”,“wid”:{“day”:“07”,“night”:“10”},“direct”:“西南风转北风”},{“date”:“2020-07-19”,“temperature”:“21/25℃”,“weather”:“大雨转中雨”,“wid”:{“day”:“09”,“night”:“08”},“direct”:“北风转东北风”},{“date”:“2020-07-20”,“temperature”:“23/28℃”,“weather”:“大雨转小雨”,“wid”:{“day”:“09”,“night”:“07”},“direct”:“南风转西南风”},{“date”:“2020-07-21”,“temperature”:“25/33℃”,“weather”:“多云转阴”,“wid”:{“day”:“01”,“night”:“02”},“direct”:“南风”}]}
* error_code : 0
*/
public interface Api {
@GET("simpleWeather/query?key=4547344eb4def925ed40ac5d067dcab0")
Call<WeatherBean> getWeather(@Query("city") String city);
}
private void requestData(String city) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://apis.juhe.cn/") //baseUrl+接口中的url为完成的请求地址
.addConverterFactory(GsonConverterFactory.create())//设置gson解析
.build();
Api api = retrofit.create(Api.class);
Call<WeatherBean> data = api.getWeather(city);
data.enqueue(new Callback<WeatherBean>() {
@Override
public void onResponse(Call<WeatherBean> call, Response<WeatherBean> response) {
WeatherBean weatherBean = response.body();
if (weatherBean.getError_code() == 0) {
//可以直接在response中操作ui
tv.setText(weatherBean.getResult().getCity() + "天气情况:\n" + "天气详情:" + weatherBean.getResult().getRealtime().toString());
} else {
tv.setText("没有查询到");
}
}
@Override
public void onFailure(Call<WeatherBean> call, Throwable t) {
tv.setText("请求错误");
Log.e(TAG, "onFailure: " + t.getMessage());
}
});
}
public interface Api {
@GET("simpleWeather/query?key=4547344eb4def925ed40ac5d067dcab0")
Observable<WeatherBean> getWeather(@Query("city") String city);
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://apis.juhe.cn/")
.addConverterFactory(GsonConverterFactory.create())//使用Gson解析
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
Api api = retrofit.create(Api.class);
Observable<WeatherBean> data = api.getWeather(city);
data.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<WeatherBean>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(WeatherBean weatherBean) {
if (weatherBean.getError_code() == 0) {
tv.setText(weatherBean.getResult().getCity() + "天气情况:\n" + "天气详情:" + weatherBean.getResult().getRealtime().toString());
Log.e(TAG, "onResponse: " + weatherBean.getResult().getCity());
} else {
tv.setText("没有查询到");
}
}
@Override
public void onError(Throwable e) {
//请求失败
}
@Override
public void onComplete() {
//请求成功
}
});
(略)
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://apis.juhe.cn/")
.addConverterFactory(GsonConverterFactory.create())//使用Gson解析
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
public Builder() {
this(Platform.get());
}
//Platform.get() 这里使用一个单例返回了Platform实例
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) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
由于retrofit同时支持Android、ios和java平台,所以在这里应该是对平台的判断
public Builder baseUrl(String baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
HttpUrl httpUrl = HttpUrl.parse(baseUrl);
if (httpUrl == null) {
throw new IllegalArgumentException("Illegal URL: " + baseUrl);
}
return baseUrl(httpUrl);
}
public Builder baseUrl(HttpUrl baseUrl) {
checkNotNull(baseUrl, "baseUrl == null");
List<String> pathSegments = baseUrl.pathSegments();
if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
}
this.baseUrl = baseUrl;
return this;
}
对传入的URL进行校验,生成httpUrl对象,然后赋值给baseUrl
在Builder()的构造方法里对各种属性进行了初始化,初始化完成后调用build方法构建Retrofit对象,此时将初始化的属性值又传给了Retrofit的构造方法。
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//callFactory就是一个okhttpClient,可见Retrofit的网络请求是通过OkhttpClient的
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
}
private final List<Converter.Factory> converterFactories = new ArrayList<>();
public Builder addConverterFactory(Converter.Factory factory) {
converterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
这里将 GsonConverterFactory.create() 创建的GsonConverterFactory对象加入了converterFactorieslist中,后面会说明
private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
adapterFactories.add(checkNotNull(factory, "factory == null"));
return this;
}
将 RxJava2CallAdapterFactory.create() 创建的RxJava2CallAdapterFactory对象加入adapterFactories数组中
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
这一步进行了很多参数校验的工作,首先判断baseUrl不能为空否则抛出异常,然后callFactory就是okhttp的工厂实例,
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
如果我们不指定CallAdapterFactory也就是不传入RxJava的callAdapter的话,会向adapterFactories数组中添加一个defaultCallAdapterFactory,也就是我们如果不指定retrofit请求数据方法的返回值类型,默认的返回值类型就是Call。而数据解析是没有默认值的。
Api api = retrofit.create(Api.class);
来看create()方法:
通过Proxy.newProxyInstance为传入的service接口创建代理对象,代理对象调用函数的时候,会调用动态代理的==invoke()==函数
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);//验证是否传入的为接口类
if (validateEagerly) {//提前创建,默认为false,这里跳过
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 {
// 方法定义所在的类,这里是定义在接口里面,返回false
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
//platform.isDefaultMethod不做处理,返回false
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
这里使用到了动态代理,构建一个 ServiceMethod 对象和 OkHttpCall 对象,并调用 serviceMethod.adapt(okHttpCall) 方法将二者绑定。在这里的adapt方法,当初始化retrofit没有使用addCallAdapterFactory的时候使用的是默认的DefaultCallAdapterFactory
@Override public Call<Object> adapt(Call<Object> call) {
return call;
}
也就是默认的返回值类型是Call类型
在创建 RxJava2CallAdapter时
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
if (rawType == Completable.class) {
// 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, isAsync, false, true, false, false,
false, true);
}
...
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
...
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
} else if (rawObservableType == Result.class) {
...
responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
isResult = true;
} else {
responseType = observableType;
isBody = true;
}
return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
isSingle, isMaybe, false);
}
在RaJava2CallAdapter中:
@Override public Object adapt(Call<R> call) {
//通过RxJava的订阅来发起请求的执行,在CallEnqueueObservable和CallExecuteObservable中dispose方法中调用了call.cancel(), 因此只要取消了RxJava的订阅就直接取消了okhttp的请求。
Observable<Response<R>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
//对结果处理,observable就是最后返回的对象
Observable<?> observable;
if (isResult) {
//Observable> 类型的返回, Result持有OkHttp的Response
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
//Observable 类型的返回
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
//Observable转化成其他的可订阅对象
if (isFlowable) {
return observable.toFlowable(BackpressureStrategy.LATEST);
}
if (isSingle) {
return observable.singleOrError();
}
if (isMaybe) {
return observable.singleElement();
}
if (isCompletable) {
return observable.ignoreElements();
}
return observable;
}
最终返回的就是observable对象
ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object, Object>)loadServiceMethod(method);
进入 loadServiceMethod(method) 方法:
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
从serviceMethodCache中取 ServiceMethod,?> 对象,如果没有,则构建 ServiceMethod, ?> 对象,然后放进去serviceMethodCache中,serviceMethodCache是一个HashMap:
private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
继续看 new ServiceMethod.Builder<>(this, method).build(); 首先看看Builder()
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit;
this.method = method;
this.methodAnnotations = method.getAnnotations();
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations();
}
这里就是对参数的一些初始化:接口方法、接口方法的注解、参数类型、参数内的注解数组。然后看看 build() 方法:
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
return new ServiceMethod<>(this);
}
首先获取了callAdapter、 responseType 、 responseConverter三个对象,然后用for循环去遍历方法中的注解并解析。
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
}
....
解析完方法的注解后,然后解析方法参数的注解数组,首先实例化了一个数组
parameterHandlers = new ParameterHandler<?>[parameterCount];
然后遍历取出参数的类型 和参数的注解 ,再把参数类型,参数注解都放在一起解析,解析的结果放入上面初始化的数组中
Type parameterType = parameterTypes[p];
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
然后看看这个方法中做了什么:
private ParameterHandler<?> parseParameter(int p, Type parameterType, Annotation[] annotations) {
ParameterHandler<?> result = null;
for (Annotation annotation : annotations) {
ParameterHandler<?> annotationAction = parseParameterAnnotation(
p, parameterType, annotations, annotation);
}
}
遍历解析参数注解,得到一个ParameterHandler对象。
然后进入 parseParameterAnnotation(
p, parameterType, annotations, annotation); 这个方法中是对参数注解的判断,然后会进入这个方法:
public <T> Converter<T, String> stringConverter(Type type, Annotation[] annotations) {
checkNotNull(type, "type == null");
checkNotNull(annotations, "annotations == null");
for (int i = 0, count = converterFactories.size(); i < count; i++) {
Converter<?, String> converter =
converterFactories.get(i).stringConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<T, String>) converter;
}
}
return (Converter<T, String>) BuiltInConverters.ToStringConverter.INSTANCE;
}
返回一个 BuiltInConverters.ToStringConverter.INSTANCE,然后回到上面的parseParameterAnnotation中
最后会返回:
return new ParameterHandler.Path<>(name, converter, path.encoded());
返回一个Path对象,并用上面的参数为它初始化。