对于OKHttp的封装,现在已经有很多方法,甚至Retrofit也是基于OkHttp封装而来。本文的封装方式不一定是最好的,但相信在某一种场景下肯定能帮助你大大简化代码。
一个普通的请求如下,采用了链式调用,使得可读性大大增加。但是如果一个页面里面有多个请求,代码量也是多很多,而每次请求都要传递参数字段,假如某个字母错了也要回到相应的界面查找。这对于代码强迫症来说是有点接受不了的。
OkHttpUtils.get()
.url(UrlAddress.GET_SCENIC_SPOTS)
.addHeader("authorization",GlobalParams.authorization)
.addParams("page","1")
.addParams("pageNum","99999")
.build()
.execute(new LiStringCallback() {
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
// showLoadingDialog("获取景区中");
}
@Override
public void onAfter(int id) {
super.onAfter(id);
// hideLoadingDialog();
}
@Override
public void onError(Call call, Exception e, int i) {
super.onError(call, e, i);
}
@Override
public void onResponse(String s, int i) {
super.onResponse(s, i);
Gson gson = new Gson();
//景区列表
SceneSpotListResult result = gson.fromJson(s, SceneSpotListResult.class);
if (result.checkCode()){
sceneList.clear();
sceneList.addAll(result.getResult().getData());
}
}
});
}
复制代码
简化思路如下,先创建OKHttp封装的接口监听LiOKHttpListen
/**
* Created by li on 2018/4/10.
* 这是OKHttp封装的接口监听
*/
public interface LiOKHttpListen {
/**
* 访问前
* @param request 请求数据
* @param requestType 操作类型
*/
void onHttpBefore(Request request,RequestType requestType);
/**
* 访问后
* @param requestType 操作类型
*/
void onHttpAfter(RequestType requestType);
/**
* 出错
* @param e 异常信息
* @param requestType 操作类型
*/
void onHttpError(Exception e,RequestType requestType);
/**
* 成功
* @param s 服务器返回数据
* @param requestType 操作类型
*/
void onHttpResponse(String s,RequestType requestType);
}
复制代码
再创建自定义的回调LiStringCallback
/**
* Created by li on 2018/4/9.
* 自定义回调
* 对接口的回调统一在这里进行。
*/
public abstract class LiStringCallback extends StringCallback {
//大帅比的接口
private LiOKHttpListen liOKHttpListen;
//大帅比的操作枚举类型
private RequestType requestType;
//普通构造方法
public LiStringCallback() {
}
//带有接口的构造方法
public LiStringCallback(LiOKHttpListen liOKHttpListen,RequestType requestType) {
this.liOKHttpListen = liOKHttpListen;
this.requestType = requestType;
}
//请求前操作
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
if (liOKHttpListen != null) {
liOKHttpListen.onHttpBefore(request,requestType);
}
}
//请求结束后操作
@Override
public void onAfter(int id) {
super.onAfter(id);
if (liOKHttpListen != null) {
liOKHttpListen.onHttpAfter(requestType);
}
}
//请求错误操作
@Override
public void onError(Call call, Exception e, int i) {
//提示网络异常
MainApp.getInstance().showMsg(R.string.common_string_http_error);
if (liOKHttpListen != null) {
liOKHttpListen.onHttpError(e,requestType);
}
}
//请求成功操作
@Override
public void onResponse(String s, int i) {
if (liOKHttpListen != null) {
liOKHttpListen.onHttpResponse(s,requestType);
}
}
}
复制代码
设置不同操作的枚举类型,RequestType的作用是同个请求可能有不同的操作,需要对之进行区分
/**
* Created by li on 2018/4/10.
* 枚举类。包括需要进行的操作,用于判断不同操作
*/
public enum RequestType {
GET_SCENE // 获取景
存放键值对数据的实体,仅方便数组请求
/**
* Created by li on 2018/4/10.
* 存放键值对数据的实体
*/
public class LiKeyBean {
//键名
String keyName;
//键值
String keyValue;
public LiKeyBean(String keyName, String keyValue) {
this.keyName = keyName;
this.keyValue = keyValue;
}
public String getKeyName() {
return keyName;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
public String getKeyValue() {
return keyValue;
}
public void setKeyValue(String keyValue) {
this.keyValue = keyValue;
}
}
复制代码
最后是okhttp管理类
/**
* Created by li on 2018/4/10.
* 面对用户使用的方法,可用post等方法
* 用户调用对应方法,并实现接口即可
*/
public class LiOKHttpUtil {
/**
* 用数据请求 post
* @param listen 实现LiOKHttpListen接口的对象
* @param url 链接
* @param heads 请求头数组
* @param params 参数数组
* @param requestType 操作类型
*/
private static void post(LiOKHttpListen listen,String url,LiKeyBean[] heads, LiKeyBean[] params ,RequestType requestType){
//获取build
PostFormBuilder postFormBuilder = OkHttpUtils.post().url(url);
//添加请求头
if (heads!=null){
for (int i=0;i<heads.length;i++){
LiKeyBean keyBean = heads[i];
if (keyBean==null) continue;
postFormBuilder.addHeader(keyBean.getKeyName(),keyBean.getKeyValue());
}
}
//添加请求
if (params!=null){
for (int i=0;i<params.length;i++){
LiKeyBean keyBean = params[i];
if (keyBean==null) continue;
postFormBuilder.addParams(keyBean.getKeyName(),keyBean.getKeyValue());
}
}
//请求
postFormBuilder .build().
execute(new LiStringCallback(listen,requestType) {
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
}
@Override
public void onAfter(int id) {
super.onAfter(id);
}
@Override
public void onError(Call call, Exception e, int i) {
super.onError(call, e, i);
}
@Override
public void onResponse(String s, int i) {
super.onResponse(s, i);
}
});
}
/**
* 用数据请求 get
* @param listen 实现LiOKHttpListen接口的对象
* @param url 链接
* @param heads 请求头数组
* @param params 参数数组
* @param requestType 操作类型
*/
private static void get(LiOKHttpListen listen, String url,LiKeyBean[] heads, LiKeyBean[] params ,RequestType requestType){
//获取build
GetBuilder getBuilder = OkHttpUtils.get().url(url);
//添加请求头
if (heads!=null){
for (int i=0;i<heads.length;i++){
LiKeyBean keyBean = heads[i];
if (keyBean==null) continue;
getBuilder.addHeader(keyBean.getKeyName(),keyBean.getKeyValue());
}
}
//添加请求
if (params!=null){
for (int i=0;i<params.length;i++){
LiKeyBean keyBean = params[i];
if (keyBean==null) continue;
getBuilder.addParams(keyBean.getKeyName(),keyBean.getKeyValue());
}
}
//请求
getBuilder .build().
execute(new LiStringCallback(listen,requestType) {
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
}
@Override
public void onAfter(int id) {
super.onAfter(id);
}
@Override
public void onError(Call call, Exception e, int i) {
super.onError(call, e, i);
}
@Override
public void onResponse(String s, int i) {
super.onResponse(s, i);
}
});
}
/**
* 用事先封装好的GetBuilder进行get请求
* @param listen 实现LiOKHttpListen接口的对象
* @param getBuilder 事先封装好的GetBuilder
* @param requestType 操作类型
*/
private static void get(LiOKHttpListen listen,GetBuilder getBuilder ,RequestType requestType){
//请求
getBuilder.build().
execute(new LiStringCallback(listen,requestType) {
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
}
@Override
public void onAfter(int id) {
super.onAfter(id);
}
@Override
public void onError(Call call, Exception e, int i) {
super.onError(call, e, i);
}
@Override
public void onResponse(String s, int i) {
super.onResponse(s, i);
}
});
}
/**
* 用事先封装好的PostFormBuilder进行post请求
* @param listen 实现LiOKHttpListen接口的对象
* @param postFormBuilder 事先封装好的PostFormBuilder
* @param requestType 操作类型
*/
private static void post(LiOKHttpListen listen,PostFormBuilder postFormBuilder ,RequestType requestType){
//请求
postFormBuilder.build().
execute(new LiStringCallback(listen,requestType) {
@Override
public void onBefore(Request request, int id) {
super.onBefore(request, id);
}
@Override
public void onAfter(int id) {
super.onAfter(id);
}
@Override
public void onError(Call call, Exception e, int i) {
super.onError(call, e, i);
}
@Override
public void onResponse(String s, int i) {
super.onResponse(s, i);
}
});
}
/**
* 获取景区
* @param listen
*/
public static void getScenes(LiOKHttpListen listen,RequestType requestType) {
GetBuilder getBuilder = OkHttpUtils.get()
.url(UrlAddress.GET_SCENIC_SPOTS)
.addHeader("authorization",GlobalParams.authorization)
.addParams("page","1")
.addParams("string","99999");
get(listen,getBuilder,requestType);
}
}
复制代码
到这一步就可以在activity里面请求了
public class MainActivity extends BaseActivity implements LiOKHttpListen {
@Override
protected int getLayoutId() {
return R.layout.main_activity_main;
}
@Override
protected void initViews() {
}
@Override
protected void onDestroy() {
}
@Override
protected void initDatas() {
getScenes();
}
@Override
protected void showContent() {
}
/**
* 获取全部景区
*/
public void getScenes(){
//一行代码就可以请求
LiOKHttpUtil.getScenes(this,RequestType.GET_SCENE);
}
@Override
public void onHttpBefore(Request request, RequestType requestType) {
switch (requestType){
case GET_SCENE:
showLoadingDialog("获取景区中");
break;
}
}
@Override
public void onHttpAfter(RequestType requestType) {
//隐藏弹窗
hideLoadingDialog();
}
@Override
public void onHttpError(Exception e, RequestType requestType) {
}
@Override
public void onHttpResponse(String s, RequestType requestType) {
switch (requestType){
case GET_SCENE:
//获取成功后的操作
break;
}
}
}
复制代码
通过以上操作就实现了笔者想要的目的,总结如下 1.抛弃了原本单个请求就可以看到全部处理的可读性,改成了全部请求通过接口返回,适用于大部分对除response之外操作不多或者重复的请求 2.将所有请求的大任都交给了LiOkHttpUtil的工具类,方便对请求管理