看了很多的Retrofit和RxJava的封装 最后自己整理了一点 自己写了一个基于RxJava和Retrofit的网络框架
基于Retrofit2.0的网络框架RetrofitClient
- 使用单例避免重复的创建RetrofitClient
- 使用接口规范网络请求
- 可动态的设置HOST
- 结合RxJava
使用原生的的Retrofit2,0访问网络 当网络接口网络请求过多时 就有点繁琐,今天是Retrofit结合RxJava网络封装的第一篇,这是Retrofit的进阶篇,如果有对Retrofit还不熟悉的朋友们,最好先看下Retrofit,下面是本篇文章的目录
- 定义接口网络接口IHttp
- 定义请求完成HttpCallBack抽象类
- 定义Retrofit2.0接口APiService
- 定义RetrofitClient
1.网络接口IHttp 里面规范了网络请求的参数 请求方式 以及回调
public interface IHttp {
void get(Class classBean, String url, Map<String, String> map, HttpCallBack httpCallBack);
void post(Class classBean, String url, Map<String, String> map, HttpCallBack httpCallBack);
}
上面定义了接口IHttp 由于时间关系只写了这两个网络请求 后面会增加上传文件(支持上传进度)下载文件(支持断点续传)
解释一下上面的参数 classBean 为请求是 最后请求结束需要生成的实体Bean对象 url为你网络地址,map为请求参数的集合,httpCallBack为请求回调
这个规范了网络请求 如果到后面需要更改网络框架 可以利用简单工厂模式直接更改网络框架
2.网络回调HttpCallBack 网络请求完成后的回调
public abstract class HttpCallBack {
public abstract void onSuccess(Object object);
public void onFailure(String message){};
}
这里必须要重写方法是onSuccess() 这个是成功的回调 里面的object可以强转为你需要的实体类Bean
有需要还可以重写失败方法onFailure() 上传下载进度方法(目前还没有)
3.网络接口ApiService
public interface IAPiService {
@GET("{url}")
Observable<ResponseBody> get(@Path("url") String url, @QueryMap Map<String, String> map);
@FormUrlEncoded
@POST("{url
}") Observable<ResponseBody> post(@Path("url"), @FieldMap Map<String, String> map);}
第一个是get请求 第二个为post请求
相对于以前的ApiService 使用注解path 可以动态的设置url,提高了代码的复用性 使用Map集合使参数更易使用
4.构建RetrofitClient
首先实现IHttp类 重写里面方法
今天最重要的环节来了 首先定义网络端口Host
public static String HOST = "http://api.wws.xywy.com/";
使用单例模式 防止多次创建对象 public static RetrofitClient getInstance() {
if (retrofitClient == null) {
synchronized (RetrofitClient.class) {
if (retrofitClient == null) {
retrofitClient = new RetrofitClient();
}
}
}
return retrofitClient;
}
在构造方法里初始化retrofit
private RetrofitClient() {
Retrofit retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(HOST)
.build();
iaPiService = retrofit.create(IAPiService.class);
}
操作重写get请求方法 @Override
public void get(Class classBean, String url, Map<String, String> map, HttpCallBack httpCallBack) {
map = getStringStringMap(map);
get(classBean, url, map, httpCallBack, false);
}
这里解释一下 我这里调用了2个方法
第一个是防止map集合为空
@android.support.annotation.NonNull
private Map<String, String> getStringStringMap(Map<String, String> map) {
if(map==null){
map = new HashMap<>();
}
return map;
}
如果map集合为空就实例化的一个HashMap 不为空直接return
第二个方法重载 如果网络请求返回的是集合 就调用重载的get方法
public void get(final Class classBean, String url, Map<String, String> map, final HttpCallBack httpCallBack, final boolean boo) {
map = getStringStringMap(map);
iaPiService.get(url, map)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getConsumer(classBean, httpCallBack, boo), getThrowable(httpCallBack));
}
这里使用RxJava 一开始把线程指定到io线程 请求完成是转到Android UI线程 这里调用了getConsumer()方法
private Consumer<ResponseBody> getConsumer(final Class classBean, final HttpCallBack httpCallBack, final boolean boo) {
Consumer<ResponseBody> consumer = new Consumer<ResponseBody>() {
@Override
public void accept(@NonNull ResponseBody responseBody) throws Exception {
String res = responseBody.string();
if (boo) {
httpCallBack.onSuccess(GsonUtils.gsonList(res, classBean));
} else {
httpCallBack.onSuccess(GsonUtils.gsonBean(res, classBean));
}
}
};
return consumer;
}
上面是自己写Gson工具类
private Consumer<Throwable> getThrowable(final HttpCallBack httpCallBack) {
Consumer<Throwable> throwable = new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
httpCallBack.onFailure(throwable.getMessage());
}
};
return throwable;
}
下面是Post请求
@Override
public void post(Class classBean, String url, Map<String, String> map, HttpCallBack httpCallBack) {
map = getStringStringMap(map);
post(classBean, url, map, httpCallBack, false);
}
public void post(Class classBean, String url, Map<String, String> map, HttpCallBack httpCallBack, boolean boo) {
map = getStringStringMap(map);
iaPiService.post(url, map)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(getConsumer(classBean, httpCallBack, boo), getThrowable(httpCallBack));
}
Gson工具类
public class GsonUtils {
private static Gson gson = null;
static {
if (gson == null) {
gson = new Gson();
}
}
private GsonUtils() {
}
//bean
public static <T> T gsonBean(String gsonString, Class<T> cls) {
T t = null;
if (gson != null) {
t = gson.fromJson(gsonString, cls);
}
return t;
}
//集合
public static <T> List<T> gsonList(String json, Class<T> cls) {
Gson gson = new Gson();
List<T> list = new ArrayList<T>();
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
for (final JsonElement elem : array) {
list.add(gson.fromJson(elem, cls));
}
return list;
}
}
看一下项目如何使用
Map<String,String> map = new HashMap<>();
map.put("act","zixun");
map.put("fun","getHealthPlazeList");
map.put("version","version2");
map.put("tag","zj");
map.put("sign","2e0d0887581be1c35794ee4c13b00cae");
map.put("typeid",typeid);
map.put("dir",dir);
RetrofitClient.getInstance().get(GaoXueYaZiXun.class, "", map, new HttpCallBack() {
@Override
public void onSuccess(Object object) {
GaoXueYaZiXun bean = (GaoXueYaZiXun) object;
Toast.makeText(App.baseActivity, "成功", Toast.LENGTH_SHORT).show();
}
});
这个只是自己写的所以没有加url 实际用的时候要加上 这样 我就可以在回调里操作请求回来的数据
暂时就写到这只是第一篇 后面会用统一添加拦截器 请求头 构建RequestBody 获取文件的上传下载进度等等