通俗易懂的Retrofit详解

概述

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);
          }
        });
  }

版权声明:本文为weixin_43841938原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。