我司项目的接口最近放开了几个,准备开始网络请求数据。本来想用Retrofit + Rxjava 的,自己尝试的封装了一下,一般般(其实是我菜,哭!)。于是乎去网上找了找有什么封装比较好的第三方,转了一圈没有什么满意的,转而其次使用OkGo,目前GitHub上面有5K+的星,还是不错的。
基本上所有功能,包括网络请求都需要进行一次二次封装,以便于以后的维护更迭,所以自己准备对OkGo进行一下封装。(我才不会说我是网上找了一下,没有找到合适的!!!网上都是的说OkGo哪里好,或者基本使用方法,好一点的提供简单的封装一下,但是根本不适合在项目中使用。)
在与我司另外一位Android程序猿合力下终于封装好了,下面记录一下思路及实现。
自己简单写的封装,要改进的很多。先这样吧!有更好的方法请联系我。
1.建立一个类,专门用来保存api,同时根据api的code,获取对应的get/post/put/delete请求。
/**
* 存放所有的API
*/
public class Urls {
//网络请求返回码
public static final int REUSLT_CODE_SUCCESS = 200;//成功
//版本号
public static int VERSION = 1;
//APICode:用于识别是那个地址的
public static final int GET_SMS_CODE = 0;//获取验证码
public static final int LOGIN_CODE = 1;//登录
//这里不列举了,以此类推
//APIUrl:具体地址
public static final String BASE_URL = "https:/xxxxx" + VERSION;
public static final String SMS_URL = BASE_URL + "/user/sms";//验证码
public static final String LOGIN_URL = BASE_URL + "/user/login";//登录
/**
* 根据APICode来获取对应的请求方式:
* GET:0 POST:1 PUT:2 DELETE:3 错误:-1
*
* @param APICode
* @return
*/
public static int getOrPost(int APICode) {
int code = -1;
switch (APICode) {
case HOME_CODE://查询首页数据
code = 0;
break;
case GET_SMS_CODE://获取验证码
case LOGIN_CODE://登录
code = 1;
break;
case SHOP_CART_CHANGE_DATA_CODE://修改购物车数据
code = 2;
break;
case SHOP_CART_DEL_DATA_CODE://删除购物车数据
code = 3;
break;
}
return code;
}
2.建立一个接口,用来请求数据成功、失败、错误的回调,就3个方法,这里就不写了。
3.建立一个转换器,用来讲获取的String的json数据转换为bean对象,(okgo文档里面有,我这里也列出来了,泛型用的贼垃圾,有大神改进的话联系我嘿嘿)
/**
* 用于将json数据转换为Bean对象
*/
public class JsonConvert implements Converter {
private Type type;
private Class clazz;
public JsonConvert(Type type) {
this.type = type;
}
public JsonConvert(Class t) {
this.clazz = t;
}
public JsonConvert() {
}
/**
* 该方法是子线程处理,不能做ui相关的工作
* 主要作用是解析网络返回的 response 对象,生成onSuccess回调中需要的数据对象
*/
@Override
public T convertResponse(Response response) throws Throwable {
ResponseBody body = response.body();
if (body == null) return null;
T data = null;
Gson gson = new Gson();
JsonReader jsonReader = new JsonReader(body.charStream());
if (type != null) data = gson.fromJson(jsonReader, type);
if (clazz != null) data = gson.fromJson(jsonReader, clazz);
return data;
}
}
4.建立一个工具类,进行请求方法设置。
public class HttpUtils
//这里对应4种请求方式。
public static final int GET = 0;
public static final int POST = 1;
public static final int PUT = 2;
public static final int DEL = 3;
/**
* get请求:返回Observable
*/
public Observable getObservable(String url, Map paramerMap, Class c) {
return OkGo.get(url)
.headers("xxx", xxx)
.converter(new JsonConvert(c))
.adapt(new ObservableBody());
}
/**
* post请求:返回Observable
*/
public Observable postObservable(String url, Map paramerMap, Class c) {
return OkGo.post(url)
.headers("xxx", xxx)
.params(paramerMap)
.converter(new JsonConvert(c))
.adapt(new ObservableBody());
}
//put和del请求同理
/**
* 请求数据
*/
public void getBeanData(final int urlCode, String url, int requestCode, Map map, Class c, final OnConnectionListener listener) {
Observer observer = new Observer() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull Object o) {
这里的listener就是第二步建立的接口
listener.onResponse(urlCode, o);
}
@Override
public void onError(@NonNull Throwable e) {
Logger.e("连接失败========" + e.toString());
listener.onError(urlCode);
}
@Override
public void onComplete() {
}
};
if (requestCode == GET) {
//get请求
getObservable(url, map, c)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(new Consumer() {
@Override
public void accept(@NonNull Disposable disposable) throws Exception {
listener.onPreConnect(urlCode);
}
})
.subscribe(observer);
} else if (requestCode == POST) {
//post请求
postObservable(url, map, c)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(new Consumer() {
@Override
public void accept(@NonNull Disposable disposable) throws Exception {
listener.onPreConnect(urlCode);
}
})
.subscribe(observer);
}
}
}
5.在model完成请求的相关监听
public class Model extends BaseModel implements OnConnectionListener {
private final Context mContext;
private final HttpUtils httpUtils;
public Model (Context context) {
this.mContext = context;
httpUtils = new HttpUtils();
}
* 获取首页的数据
*/
public Model getHomeData() {
//进行联网
Map map = new HashMap<>();
httpUtils.getBeanData(Urls.HOME_CODE, Urls.HOME_URL, Urls.getOrPost(Urls.HOME_CODE), map,HomeBean.class, this);
return this;
}
/**
* 对请求的回调: 请求之前
*
* @param responseCode
*/
@Override
public void onPreConnect(int responseCode) {
}
//请求成功
@Override
public void onResponse(int responseCode, Object o) {
switch (responseCode) {
case Urls.HOME_CODE://首页数据
HomeBean homeBean = (HomeBean) o;
int code = homeBean.getCode();
if (code == 200) {
mOnRequestListener.onSuccessed(responseCode, o);
} else {
String message = homeBean.getMessage();
mOnRequestListener.onFailed(responseCode, message);
}
break;
}
}
//请求失败
@Override
public void onError(int responseCode) {
}
/**
* 联网请求数据之后的接口回调
*/
private OnRequestListener mOnRequestListener;
public void setOnRequestListener(OnRequestListener listener) {
this.mOnRequestListener = listener;
}
}
6.具体请求
直接在代码中,model.getHomeData().setOnRequestListener(this);然后实现接口,就会有数据回调。
其实有很多地方没有处理好比如说 httpUtils里面就可以优化很多,目前还没有好的想法。包括model也有很多的优化要做的。