在《Android网络请求框架-----Retrofit(动态代理模式)》中,简单介绍了一下Retrofit的底层实现原理,这一节主要介绍一下Retrofit的使用。
1.Retrofit的优点
API简单、使用注解高度解耦合、支持多种解析器、支持RxJava。
2.使用
在介绍了Retrofit的这些优点之后,从使用角度来看一下它的优点是如何具体实现的。
(1)在使用之前,需要做一些配置,加入Retrofit的依赖库、Okhttp的依赖库以及数据解析库
implementation 'com.squareup.retrofit2:retrofit:2.7.1'implementation 'com.squareup.okhttp:okhttp:2.7.5'implementation 'com.squareup.retrofit2:converter-gson:2.7.1'
(2)创建接口,设置请求参数
首先我们先创建一个实体类DataBean,一般是根据 返回的数据类型创建的,这个和一般数据解析是一样的,像在使用Gson或者fastJson解析JsON数据时,创建的实体类一致;
public interface UpdateService { @GET("getAppConfig.PHP") public Call<DataBean> update( //内部是请求的参数 @query("appID") String appID );}
然后创建一个接口,注明我们想要请求的地址,以及请求的参数。
常用到的一些参数注解:
@GET | get请求 |
---|---|
@POST | post请求 |
@Path | 动态的URL代替 |
@query | 要传递的参数 |
@queryMap | 多参数(可能超过10个) |
@Body | 添加实体类对象 |
(3)创建Retrofit对象,设置数据解析器,执行网络请求,得到响应数据
Retrofit retrofit = new Retrofit.Builder().baseUrl(Constant.BASE_URL) .addConverterFactory(GsonConverterFactory.create()).build(); UpdateService updateService = retrofit.create(UpdateService.class); Call<DataBean> call = updateService.update("ceshiqianggeng777"); call.enqueue(new Callback<DataBean>() { @OverrIDe public voID onResponse(Call<DataBean> call, Response<DataBean> response) { //请求成功,返回是一个封装为DataBean的响应 String url = response.body().getUrl(); Log.e("TAG","Url ===== "+url); } @OverrIDe public voID onFailure(Call<DataBean> call, Throwable t) { //请求失败 } });
运行后,已经成功获取DataBean响应中的url字段。
2020-02-06 17:16:47.147 2407-2407/com.example.myapplication E/TAG: Url ===== https://andownload.yyguokang120.com/bxvip/androIDapk/152caizy01.apk
简单总结一下关于Retrofit的使用和Okhttp的对比:
(1)在使用Okhttp处理数据时,获取的数据需要去手动解析,像JsON数据,需要去根据JsON数据去创建实体类,然后获取数据,虽然不难,但是也需要几个步骤;Retrofit是直接在响应中,就将实体类封装到了这个Response中,不需要再去手动解析。
(2)我在这里没有去更新UI,像在使用Okhttp的时候,获取的数据需要去返回到主线程获取数据更新UI,但是在使用Retrofit不需要这样,直接在onResponse
中更新UI
@OverrIDepublic voID onResponse(Call<DataBean> call, Response<DataBean> response) { //请求成功,返回是一个封装为DataBean的响应 String url = response.body().getUrl(); Log.e("TAG","Url ===== "+url); //可直接在此更新UI }
3.动态配置url
在网络请求中,base_url不会变,但是请求的参数可能会变,因此如果在接口类中,写死了@GET后边的请求参数,不具备扩展性,因此动态配置url,可以使用@Path
假设我这个GET请求可能目前请求的是这个接口,然后还有其他的接口,那么就可以把这个参数 “getAppConfig.PHP” 作为Path的字段值,然后用{ }括起来;
public interface UpdateService { @GET("{path}") public Call<DataBean> update( //内部是请求的参数 @Path("path") String path, @query("appID") String appID );}
和刚开的做对比
public interface UpdateService { @GET("getAppConfig.PHP") public Call<DataBean> update( //内部是请求的参数 @query("appID") String appID );}
Call<DataBean> call = updateService.update("getAppConfig.PHP","ceshiqianggeng777");
其实两者请求的都是同一个url:
baseurl/getAppConfig.PHP?appID=ceshiqianggeng777
如果你之前使用的都是Okhttp,那么第一次使用Retrofit,有没有爱不释手的感觉呢?
4.自定义类型转换
在之前使用Retrofit的时候,使用到了数据解析器是GsonConverterFactory,这个解析器内部的源码:
public final class GsonConverterFactory extends Converter.Factory { /** * Create an instance using a default {@link Gson} instance for conversion. EnCoding to JsON and * deCoding from JsON (when no charset is specifIEd by a header) will use UTF-8. */ public static GsonConverterFactory create() { return create(new Gson()); } /** * Create an instance using {@code gson} for conversion. EnCoding to JsON and * deCoding from JsON (when no charset is specifIEd by a header) will use UTF-8. */ @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static GsonConverterFactory create(Gson gson) { if (gson == null) throw new NullPointerException("gson == null"); return new GsonConverterFactory(gson); } private final Gson gson; private GsonConverterFactory(Gson gson) { this.gson = gson; } @OverrIDe public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(Typetoken.get(type)); return new GsonResponseBodyConverter<>(gson, adapter); }//这个方法目前没用到,因为我们没有使用post请求。 @OverrIDe public Converter<?, Requestbody> requestbodyConverter(Type type, Annotation[] parameterannotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(Typetoken.get(type)); return new GsonRequestbodyConverter<>(gson, adapter); }}
这个数据解析器,在内部是new Gson(),然后在获取数据响应,也就是ResponseBody的时候,将其转换为JavaBean,这个过程是在responseBodyConverter
方法中进行的,在获取了当前的数据类型之后,最终返回了一个GsonResponseBodyConverter
对象
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(); } }}
在GsonResponseBodyConverter
方法当中,有一个convert方法,就是获取了ResponseBody的数据流后,利用Gson将这个数据流转换为对应类型的JavaBean。
这也是在我们使用Retrofit的时候,在获取响应的时候,已经为我们封装好了JavaBean的响应。
如果在实际的使用中,除了使用Gson转换之外,比如我们还想将时间类型转换为String类型的数据,那么我们也可以自定义数据解析器。
public class DateConvertFactory extends Converter.Factory { //将时间类型转换为String 类型 @OverrIDe public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) { if(type == Date.class){ //就去进行类型转换 return new DateConvert(); } return super.stringConverter(type, annotations, retrofit); } private class DateConvert implements Converter<Date, String> { private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); @OverrIDe public String convert(Date value) throws IOException { return sdf.format(value); } } public static DateConvertFactory create(){ return new DateConvertFactory(); }}
其实这个自定义的数据解析器是跟Gson数据解析器的思想是一样的,GsonConverterFactory 是继承自Converter.Factory,然后继承这个父类,除了可以重写toString之外,还有
这些在Gson数据解析器中有体现。
在自定义的这个数据解析中,也是继承了Converter.Factory,重写了其中的stringConverter
方法,这个方法可以将某个类型转换为String类型,如果判断是Date类型,那么就去进行类型转换。
类型转换是实现了Converter<Date, String>
接口,将Date转换为String,重写了convert方法。
好了,以上就是Retrofit的简单的使用,后续还会继续更新!
点赞1收藏分享文章举报那年1月26日那一天发布了13 篇原创文章 · 获赞 3 · 访问量 351私信 关注 总结以上是内存溢出为你收集整理的Android网络请求框架------Retrofit的使用全部内容,希望文章能够帮你解决Android网络请求框架------Retrofit的使用所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)