Retrofit网络框架:结合RxJava、Gson简化网络请求
Retrofit是一个流行的网络请求框架,可以将声明的网络请求接口通过动态代理的方式生成具体的请求,内部实际使用OkHttp进行网络请求,可以使用Gson处理请求的数据,使用RxJava进行线程的切换。下面从基础的Retrofit请求开始,依次添加OkHttp配置、Gson、RxJava简化网络请求。
接口来源:和风天气api, 网络请求key需要自己申请
1、Retrofit进行基础网络请求
首先创建一个基础的Retrofit实例:
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
.build();
然后声明网络请求接口:
public interface QWeatherApi1 {
@GET("/v7/weather/now")
Call<ResponseBody> queryNow(@Query("key") String key,
@Query("location") String location);
}
进行网络请求:
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
.build();
QWeatherApi1 api1 = retrofit.create(QWeatherApi1.class);
api1.queryNow(key, "101010100").enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(@NotNull Call<ResponseBody> call,
@NotNull retrofit2.Response<ResponseBody> response) {
try {
System.out.println(response.code());
System.out.println("onResponse(" + response.body().string());
//Retrofit内部进行了线程切换, 当前是主线程
System.out.println(Looper.myLooper());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
System.out.println("onFailure(" + t.getMessage());
}
});
2、添加OkHttp配置:统一配置超时时间、认证等
进行网络请求时需要统一配置超时时间等,同时还需要进行认证(如天气请求时统一的key), 这可以通过添加自定义的OkHttpClient来实现。
OkHttpClient client = new OkHttpClient.Builder()
//连接超时时间
.connectTimeout(10, TimeUnit.SECONDS)
//读超时时间
.readTimeout(10, TimeUnit.SECONDS)
//写超时时间
.writeTimeout(10, TimeUnit.SECONDS)
.addInterceptor(new Interceptor() {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
//统一添加接口需要的key
RealInterceptorChain realInterceptorChain = (RealInterceptorChain) chain;
Request request = realInterceptorChain.request();
HttpUrl.Builder builder = request.url().newBuilder();
builder.addQueryParameter("key", key);
return chain.proceed(request.newBuilder().url(builder.build()).build());
}
})
.build();
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
.client(client)
.build();
于是网络请求接口可以简化为:
public interface QWeatherApi2 {
@GET("/v7/weather/now")
Call<ResponseBody> queryNow(@Query("location") String location);
}
同样地,如下进行网络请求:
QWeatherApi2 api2 = retrofit.create(QWeatherApi2.class);
api2.queryNow("101010100").enqueue(
...
);
3、添加Gson解析
网络请求回来的数据需要转成model, Retrofit提供了相关接口,可以通过Gson将请求回来的字符串转成model。
添加依赖:
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.8.7'
Retrofit创建时增加解析Factory:
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
//使用gson进行json到model的转换
.addConverterFactory(GsonConverterFactory.create())
//okhttp进行数据实际请求
.client(client)
.build();
网络请求接口可以写成:
public interface QWeatherApi3 {
@GET("/v7/weather/now")
Call<NowWeatherResponse> queryNow(@Query("location") String location);
}
于是网络请求如下:
QWeatherApi3 api3 = retrofit.create(QWeatherApi3.class);
api3.queryNow("101010100").enqueue(new Callback<NowWeatherResponse>() {
@Override
public void onResponse(Call<NowWeatherResponse> call,
retrofit2.Response<NowWeatherResponse> response) {
System.out.println(response.body());
}
@Override
public void onFailure(Call<NowWeatherResponse> call, Throwable t) {
System.out.println("onFailure(" + t.getMessage());
}
});
4、RxJava简化处理流程
如果需要对返回的数据进一步处理,那么使用RxJava是一个比较好的选择。RxJava能够方便的进行上下文切换,可以将复杂、耗时的操作放到非主线程中执行,然后在主线程返回结果。
引入RxJava依赖:
implementation 'io.reactivex.rxjava2:rxjava:2.2.7'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "com.squareup.retrofit2:adapter-rxjava2:2.9.0"
将RxJava配置到Retrofit中:
Retrofit retrofit = new Retrofit.Builder().baseUrl("https://devapi.qweather.com")
//使用gson进行json到model的转换
.addConverterFactory(GsonConverterFactory.create())
//使用rxjava管理数据的处理与线程切换
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//okhttp进行数据实际请求
.client(client)
.build();
然后修改网络请求接口声明:
public interface QWeatherApi4 {
@GET("/v7/weather/now")
Observable<NowWeatherResponse> queryNow(@Query(value = "location") String
location);
}
于是网络请求如下:
QWeatherApi4 api4 = retrofit.create(QWeatherApi4.class);
api4.queryNow("101010100")
.map(nowWeatherResponse -> {
// 这里是io线程,可以进行复杂耗时的操作
System.out.println("线程:" + Thread.currentThread());
return nowWeatherResponse;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(nowWeatherResponse -> {
// 这里已经是主线程了,
System.out.println("线程:" + Thread.currentThread());
return nowWeatherResponse;
})
.subscribe(new Observer<NowWeatherResponse>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
list.add(d);
}
@Override
public void onNext(@NonNull NowWeatherResponse weatherResponse) {
System.out.println("onNext:" + weatherResponse);
System.out.println("onNext(线程:" + Thread.currentThread());
}
@Override
public void onError(@NonNull Throwable e) {
System.out.println("onError:" + e.getMessage());
e.printStackTrace();
}
@Override
public void onComplete() {
}
});