最近因为项目中使用Retrofit联网请求遇到问题,特意研究了下Retrofit的实现和原理。
总的来说,Retrofit不直接做网络请求,而是用OKhttp做联网请求,相当于一个联网请求适配器。
网络请求的目标虽然是数据,但是我们需要为这个数据写大量的配套代码,发起请求的对象Call,接收数据的对象CallBack,做数据转换的对象Converter,以及检查和处理异常的对象等。这对于一个项目的开发、扩展和维护来说,都是成本和风险。
而Retrofit做的事情,就是为开发者节省这部分的工作量,Retrofit一方面从底层统一用OkHttp去做网络处理;另一方面在外层灵活提供能直接融入业务逻辑的Call网络访问对象。
就是说,Retrofit只负责生产对象,生产能做网络请求的工作对象,他类似工厂模式,只提供产品,工厂本身不处理网络请求,产品才能处理网络请求。
Retrofit实现原理分四大块——动态代理,函数解析、网络请求和数据转换。
Retrofit2.0中的注解
请求方法的注解 @GET、@POST、@PUT、@DELATE、@HEAD、@PATCH、@OPTIONS、@HTTP
标记注解 @FormUrlEncoded、@Multipart、@Streaming
参数注解 @Path 、@Field、 @FieldMap、 @Part、 @PartMap、 @Query、 @QueryMap、 @Body、 @Url、 @Header、 @Headers
因为之前因为请求注解这块理解问题,导致联网请求一直失败。这块需要根据业务情况好好理解合理使用。
定义接口
Retrofit要求定义一个网络请求的接口,接口函数里要定义url路径、请求参数、返回类型。
public interface INetApiService {
@GET("/demobiz/api.php")
Call getBizInfo(@Query(“id”) String id);
}
在这个接口定义中,用注解@GET("/demobiz/api.php")声明了url路径,用注解@Query(“id”) 声明了请求参数。
最重要的是,用Call声明了返回值是一个Retrofit的Call对象,并且声明了这个对象处理的数据类型为BizEntity,BizEntity是我们自定义的数据模型。
依次获得Retrofit对象、接口实例对象、网络工作对象
首先,需要新建一个retrofit对象。
然后,根据上一步的接口,实现一个retrofit加工过的接口对象。
最后,调用接口函数,得到一个可以执行网络访问的网络工作对象。
这里理解的万物皆对象原则,Retrofit接口是一个对象,本身也是一个对象,这个联网请求还是一个对象。非常精妙!
使用简单说明:先在项目里添加依赖
dependencies {
//retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
//转换器,请求结果转换成Model
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
//Gson 库
implementation 'com.google.code.gson:gson:2.6.2'
}
在AndroidManifest.xml添加联网权限:
<uses-permission android:name=“android.permission.INTERNET”
然后就可以创建Retrofit对象,定义接口实现联网请求了。
ProjectAPIService apiService = RetrofitUtils.retrofit.create(ProjectAPIService.class);
apiService.doLogin(Constants.ROOT_URL + Constants.GET_USER_LOGIN, map1).enqueue(new MyCallBack3<BaseCallModel3<ResultValueBean>>() {
@Override
public void onSuc(Response<BaseCallModel3<ResultValueBean>> response) {
if (response.isSuccessful() && response.raw().code() == 200) {
Constants.Cookie = response.headers().get("Set-Cookie");
Retrofit的目标:避免为网络访问开发大量的配套代码。
我们的目标,以最少的代码实现最完美的功能!!!