Kevin Learn RecyclerView--> Retrofit + RxJava + OkHttp 网络请求
Posted Kevin_小飞象
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kevin Learn RecyclerView--> Retrofit + RxJava + OkHttp 网络请求相关的知识,希望对你有一定的参考价值。
简介
-
Retrofit 是 Square 公司开发的一款正对 android 网络请求的框架。底层基于 OkHttp 实现,OkHttp 已经得到了 google 官方的认可。
-
OkHttp 也是 Square 开源的网络请求库
-
RxJava 在 GitHub 主页上的自我介绍是 " a library for composing asynchronous and event-based programs using observable sequences for the Java VM "(一个在 Java VM 上使用可观测的序列来组成异步的、基于事件的程序的库)。这就是 RxJava ,概括得非常精准。总之就是让异步操作变得非常简单。
职责:Retrofit 负责请求的数据和请求的结果,使用接口的方式呈现,OkHttp 负责请求的过程,RxJava 负责异步,各种线程之间的切换。
RxJava + Retrofit + okHttp 已成为当前 Android 网络请求最流行的方式。
网络请求
1. 在 app/build.gradle 中添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'io.reactivex:rxjava:1.2.1'
implementation 'io.reactivex:rxandroid:1.2.1'
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
2. 创建一个统一生成接口实例的管理类
/**
* Created on 2022/3/18 10:33
*
* @author Gong Youqiang
*/
public class RetrofitServiceManager
private static final int DEFAULT_TIME_OUT = 5;//超时时间 5s
private static final int DEFAULT_READ_TIME_OUT = 10;
private Retrofit mRetrofit;
private RetrofitServiceManager()
// 创建 OKHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS);//连接超时时间
builder.writeTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//写操作 超时时间
builder.readTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//读操作超时时间
// 添加公共参数拦截器
HttpCommonInterceptor commonInterceptor = new HttpCommonInterceptor.Builder()
.addHeaderParams("paltform","android")
.addHeaderParams("userToken","1234343434dfdfd3434")
.addHeaderParams("userId","123445")
.build();
builder.addInterceptor(commonInterceptor);
// 创建Retrofit
mRetrofit = new Retrofit.Builder()
.client(builder.build())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Constants.BASE_URL)
.build();
private static class SingletonHolder
private static final RetrofitServiceManager INSTANCE = new RetrofitServiceManager();
/**
* 获取RetrofitServiceManager
* @return
*/
public static RetrofitServiceManager getInstance()
return SingletonHolder.INSTANCE;
/**
* 获取对应的Service
* @param service Service 的 class
* @param <T>
* @return
*/
public <T> T create(Class<T> service)
return mRetrofit.create(service);
说明:创建了一个RetrofitServiceManager类,该类采用单例模式,在私有的构造方法中,生成了Retrofit 实例,并配置了OkHttpClient和一些公共配置。提供了一个create()方法,生成接口实例,接收Class范型,因此项目中所有的接口实例Service都可以用这个来生成,代码如下:
mGankService = RetrofitServiceManager.getInstance().create(GankService.class);
3. 网络请求结果基类
/**
* Created on 2022/3/18 10:26
* 网络请求结果基类
* @author Gong Youqiang
*/
public class BaseResponse<T>
public int status;
public String message;
public T data;
public boolean isSuccess()
return status == 200;
4. 创建一个业务 ObjectLoader
/**
* Created on 2022/3/18 10:31
* 将一些重复的操作提出来,放到父类以免Loader 里每个接口都有重复代码
* @author Gong Youqiang
*/
public class ObjectLoader
/**
*
* @param observable
* @param <T>
* @return
*/
protected <T> Observable<T> observe(Observable<T> observable)
return observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
5. 拦截器
/**
* Created on 2022/3/18 10:30
* 拦截器
* @author Gong Youqiang
*/
public class HttpCommonInterceptor implements Interceptor
private Map<String,String> mHeaderParamsMap = new HashMap<>();
public HttpCommonInterceptor()
@Override
public Response intercept(Chain chain) throws IOException
Log.d("HttpCommonInterceptor","add common params");
Request oldRequest = chain.request();
// 新的请求
Request.Builder requestBuilder = oldRequest.newBuilder();
requestBuilder.method(oldRequest.method(), oldRequest.body());
//添加公共参数,添加到header中
if(mHeaderParamsMap.size() > 0)
for(Map.Entry<String,String> params:mHeaderParamsMap.entrySet())
requestBuilder.header(params.getKey(),params.getValue());
Request newRequest = requestBuilder.build();
return chain.proceed(newRequest);
public static class Builder
HttpCommonInterceptor mHttpCommonInterceptor;
public Builder()
mHttpCommonInterceptor = new HttpCommonInterceptor();
public Builder addHeaderParams(String key, String value)
mHttpCommonInterceptor.mHeaderParamsMap.put(key,value);
return this;
public Builder addHeaderParams(String key, int value)
return addHeaderParams(key, String.valueOf(value));
public Builder addHeaderParams(String key, float value)
return addHeaderParams(key, String.valueOf(value));
public Builder addHeaderParams(String key, long value)
return addHeaderParams(key, String.valueOf(value));
public Builder addHeaderParams(String key, double value)
return addHeaderParams(key, String.valueOf(value));
public HttpCommonInterceptor build()
return mHttpCommonInterceptor;
6. PayLoad.java
/**
* Created on 2022/3/18 10:32
*
* @author Gong Youqiang
*/
public class PayLoad<T> implements Func1<BaseResponse<T>,T>
@Override
public T call(BaseResponse<T> tBaseResponse) //获取数据失败时,包装一个Fault 抛给上层处理错误
if(!tBaseResponse.isSuccess())
throw new Fault(tBaseResponse.status,tBaseResponse.message);
return tBaseResponse.data;
7. 异常处理类
/**
* Created on 2022/3/18 10:29
* 异常处理类,将异常包装成一个 Fault ,抛给上层统一处理
* @author Gong Youqiang
*/
public class Fault extends RuntimeException
private int errorCode;
public Fault(int errorCode,String message)
super(message);
errorCode = errorCode;
public int getErrorCode()
return errorCode;
8. BasicParamsInterceptor.java
/**
* Created on 2022/3/18 10:27
*
* @author Gong Youqiang
*/
public class BasicParamsInterceptor implements Interceptor
Map<String, String> queryParamsMap = new HashMap<>();
Map<String, String> paramsMap = new HashMap<>();
Map<String, String> headerParamsMap = new HashMap<>();
List<String> headerLinesList = new ArrayList<>();
private BasicParamsInterceptor()
@Override
public Response intercept(Chain chain) throws IOException
Request request = chain.request();
Request.Builder requestBuilder = request.newBuilder();
// process header params inject
Headers.Builder headerBuilder = request.headers().newBuilder();
if (headerParamsMap.size() > 0)
Iterator iterator = headerParamsMap.entrySet().iterator();
while (iterator.hasNext())
Map.Entry entry = (Map.Entry) iterator.next();
headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
if (headerLinesList.size() > 0)
for (String line: headerLinesList)
headerBuilder.add(line);
requestBuilder.headers(headerBuilder.build());
// process header params end
// process queryParams inject whatever it's GET or POST
if (queryParamsMap.size() > 0)
request = injectParamsIntoUrl(request.url().newBuilder(), requestBuilder, queryParamsMap);
// process post body inject
if (paramsMap.size() > 0)
if (canInjectIntoBody(request))
FormBody.Builder formBodyBuilder = new FormBody.Builder();
for(Map.Entry<String, String> entry : paramsMap.entrySet())
formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue());
RequestBody formBody = formBodyBuilder.build();
String postBodyString = bodyToString(request.body());
postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
request = requestBuilder.build();
return chain.proceed(request);
private boolean canInjectIntoBody(Request request)
if (request == null)
return false;
if (!TextUtils.equals(request.method(), "POST"))
return false;
RequestBody body = request.body();
if (body == null)
return false;
MediaType mediaType = body.contentType();
if (mediaType == null)
return false;
if (!TextUtils.equals(mediaType.subtype(), "x-www-form-urlencoded"))
return false;
return true;
// func to inject params into url
private Request injectParamsIntoUrl(HttpUrl.Builder httpUrlBuilder, Request.Builder requestBuilder, Map<String, String> paramsMap)
if (paramsMap.size() > 0)
Iterator iterator = paramsMap.entrySet().iterator();
while (iterator.hasNext())
Map.Entry entry = (Map.Entry) iterator.next();
httpUrlBuilder.addQueryParameter((String) entry.getKey(), (String) entry.getValue());
requestBuilder.url(httpUrlBuilder.build());
return requestBuilder.build();
return null;
private static String bodyToString(final RequestBody request)
try
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if(copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
catch (final IOException e)
return "did not work";
public static class Builder
BasicParamsInterceptor interceptor;
public Builder()
interceptor = new BasicParamsInterceptor();
public Builder addParam(String key, String value)
interceptor.paramsMap.put(key, value);
return this;
public Builder addParamsMap(Map<String, String> paramsMap)
interceptor.paramsMap.putAll(paramsMap);
return this;
public Builder addHeaderParam(String key, String value)
interceptor.headerParamsMap.put(key, value);
return this;
public Builder addHeaderParamsMap(Map<String, String> headerParamsMap)
interceptor.headerParamsMap.putAll(headerParamsMap);
return this;
public Builder addHeaderLine(String headerLine)
int index = headerLine.indexOf(":");
if (index == -1)
throw new IllegalArgumentException("Unexpected header: " + headerLine);
interceptor.headerLinesList.add(headerLine);
return this;
public Builder addHeaderLinesList(List<String> headerLinesList)
for (String headerLine: headerLinesList)
int index = headerLine.indexOf(":");
if (index == -1)
throw new IllegalArgumentException("Unexpected header: " + headerLine);
interceptor.headerLinesList以上是关于Kevin Learn RecyclerView--> Retrofit + RxJava + OkHttp 网络请求的主要内容,如果未能解决你的问题,请参考以下文章
Kevin Learn RecyclerView--> 实现二级列表
Kevin Learn Recyclerview-->Leanback 中的 HorizontalGridView
Kevin Learn Recyclerview-->UltimateRecyclerView 的基本使用
Kevin Learn RecyclerView--> Retrofit + RxJava + OkHttp 网络请求