概述
Retrofit主要是利用动态代理的方式,获取其执行时的方法上的注解+形参等数据,并保存于serviceMethod对象中。serviceMethod和args(形参的值)全都存入OkHttpCall中,serviceMethod.adapt最终返回的是将serviceMethod和okHttpCall绑在了一起。调用Call的enqueue()—>OkHttpCall的enqueue()—>okhttp的enqueue()。得到数据回调对应的方法中
注解
方法注解:@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTION
List item
S、@HTTP。
标记注解:@FormUrlEncoded【返回表单】、@Multipart【用于文件上传】、@Streaming【返回数据量特别大使用】。
参数注解:@Query,@QueryMap;@Body;@Field、@FieldMap;@Part,@PartMap。
其他注解:@Path;@Header,@Headers;@Url
流程
interface xxxService {
@GET
Observable<String> get(@Url String url, @QueryMap Map<String, Object> params);
@GET
Observable<String> getRaw(@Url String url, @Body RequestBody body);
@FormUrlEncoded
@POST
Observable<String> post(@Url String url, @FieldMap Map<String, Object> params);
@POST
Observable<String> postJson(@Url String url, @Body RequestBody body);
@GET("wxarticle/list/{id}/{page}/json")
fun getAirticles(@Path("id") id: String, @Path("page") page: String): Call<BaseData>
}
下面代码中最后的build作用是将前面的一些参数(baseUrl,转换器,适配器等)什么的都配置到Retrofit对象里面。
Retrofit mRetrofit=new Retrofit.Builder()
.baseUrl("https://wanandroid.com/")
.addConverterFactory(GsonConverterFactory.create()) //数据解析器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
我们先看下前面写的接口
Call<String> login( @Body User ueser);
如果返回的是Observable格式,则这么定义接口:
Observable<String> login(@Body User ueser);
从上面可以看到, Retrofit接口的返回值分为两部分,一部分是前面的Call或者Observable,另一部分是String。
1)addCallAdapterFactory影响的就是第一部分的Call或者Observable,Call类型是默认支持的(内部由DefaultCallAdapterFactory支持),而如果要支持Observable,我们就需要自己添加
addCallAdapterFactory(RxJavaCallAdapterFactory.create())
2)addConverterFactory影响的就是第二部分以及我们的请求参数,将服务器返回的数据转换成String
/***将接口转换成了实现类,调用自定义api,请求数据***/
/***方式一***/
Map<String, Object> mParams = new HashMap<String, Object>();
map.put("name","123");
//用接口生成实例
val service= mRetrofit.create(xxxService::class.java)
//调用方法 返回Observable对象
val observable= service.post("xxx/xxx", mParams)
//被观察者订阅观察者,正常应该反过来,其实这么做是为了链式调用
observable.subscribe(new Observer() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Object o) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
/***方式二***/
//用接口生成实例
val service= mRetrofit.create(xxxService::class.java)
//调用方法 返回Call对象
val airticlesCall = service.getAirticles("408", "1")
//异步请求方式
airticlesCall.enqueue(object : Callback<BaseData> {
override fun onFailure(call: Call<BaseData>, t: Throwable) {
//请求失败
t.printStackTrace()
Log.e("xfhy", "请求失败")
}
override fun onResponse(call: Call<BaseData>, response: Response<BaseData>) {
//请求成功
val baseData = response.body()
Log.e("xfhy", "请求成功 ${baseData?.toString()}")
}
})
mRetrofit.create(xxxService::class.java),这一句代码将接口转换成了实现类,使我们可以调用我们自定义的api。
通过动态代理的方式,获取其执行时的方法上的注解+形参等数据,并保存于serviceMethod对象中。serviceMethod和args(形参的值)全都存入OkHttpCall中,serviceMethod.adapt最终返回的是将serviceMethod和okHttpCall绑在了一起。
public <T> T create(final Class<T> service) {
//这里传入的必须是接口
Utils.validateServiceInterface(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 {
....
//读取method中的所有数据 将是网络请求的所有入参
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
//各种注解啊,数据啊都传过去 args是方法的参数数据
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}