前言:今天记录一下最近使用比较多的一个网络请求框架,也就是今天的主角Retrofit+RxJava。对于RxJava其实就是对异步操作的封装,对于它的评价优劣参半(本人对其的态度比较中立,这也可以与本人的理念相关,我是一个注重结果的人,使用什么框架对我来说并不是很紧要)。而Retrofit是什么呢?它其实是对OkHttp进一步的封装,实质上还是由OkHttp完成网络的请求加载。既然这样为什么还要选择Retrofit呢?其实对于我个人而言还是无所谓,只要能完成需求直接用OkHttp甚至用最原始的那几种都是可以的。不好意思。。。有点跑题了!Retrofit是对网络请求接口进行了封装,这不仅便于我们的接口调用,也使得代码更加美观。
废话说了一堆,现在开始体验一下吧。
Step1,添加依赖
我们需要添加RxJava、OkHttp以及Retrofit的依赖
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'com.squareup.retrofit2:retrofit:2.3.0' implementation 'com.squareup.retrofit2:converter-gson:2.3.0' implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar' compile 'com.squareup.okhttp3:okhttp:3.4.1' compile 'com.squareup.okio:okio:1.9.0'
Step2,创建接口
我们创建一个名为Api的接口文件,并定义相关的接口。我们需要提前了解Retrofit的一些注解,大家可以上网搜索“Retrofit注解”,相关的文章是很多的。代码如下:
public interface Api { //好友列表 @FormUrlEncoded @POST("api/talk/class_user_list") Call<ResponseBody> getFriends(@Field("classid") String classid); }
Step3,创建Retrifit对象RetrofitBean
直接贴代码了,相关的解释都在注释里面
public class RetrofitBean { private static Api api; public static Api getApi(){ api = null; OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder(); //初始化retrofit框架 Retrofit build = new Retrofit.Builder() .client(okHttpBuilder.build()) //1.配置主机地址 .baseUrl(com.example.administrator.retrofitdemo.Retrofit.HttpUrl.BASE_URLAPI) //2.解析json的工具 .addConverterFactory(GsonConverterFactory.create(new Gson())).build(); //读取接口上面的参数 api = build.create(Api.class); return api; } }
Step4,调用接口
我们定义一个getFriend方法请求数据,并将取到的数据渲染到界面
public void getFirend() { Call<ResponseBody> data = RetrofitBean.getApi().getFriends("4"); retrofit2.Callback<ResponseBody> callback = new retrofit2.Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { try { tv.setText(response.body().string()); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { } }; data.enqueue(callback); }
上面几步就是该框架的简单用法,虽然能完成我们的基本需求,但是存在一些bug会造成不好的用户体验,且无法完美满足我们的真实需求。下面就介绍我遇到过的几个问题和我的解决方案。
1、连续请求。
最初的时候,我是一个Activity中定义一个Call对象,但是会出现这么一种情况,当这个Activity中需要多个接口或者需要连续请求多次接口的时候,经常会出现数据错乱或者应用崩掉的现象。刚遇到这种问题的时候,我理索然的认为是网络不稳定的原因,可是我发现经常会出现这种问题,就决定深入排查一下问题。从网上查阅资料,最后发现有两种方法解决,一个是改成同步请求(这种方式不能在主线程中使用并且效率较低,不采用);第二种方法就是每次请求的时候重新定义一个Call对象。
2、请求为完成。
有时候,当前Activity请求未完成便退出并重新打开一个新的会请求网络的Activity会出现应用崩掉。这就需要我们及时取消掉未完成的请求,我们可以利用call.cancel();完成取消请求。
3、response.body().string()不能重复使用
在一个回调中该方法只可以调用一次,再次调用返回的则是null对象。但是实际应用中,我们需要多次用到这个结果,那么我们便定义一个String对象,之后直接操作String对象即可,