最近学习了Retrofit+Rxjava+MVP,正好有个需求要做网络请求,于是就又开始撸起代码了,关于上面两个框架的具体使用我在这里就不再多说了,大家可以看看人家大牛的博客,下面直接进入正题
一、首先我们看看服务器给我们返回的数据类型json的格式,这是自己简单写的一个后台接口
{"code":66,
"message":"登录成功",
"data":[{"id":3,"phone":"123","password":"nian","idCard":"2450","money":"100","name":"ni"}]}
二、客户端这边的数据解析类,主要解析用户类数据
public class User {
private int id;
private String phone;
private String password;
private String idCard;
private String money;
private String name;
public User(int id, String phone, String password, String idCard, String money, String name) {
this.id = id;
this.phone = phone;
this.password = password;
this.idCard = idCard;
this.money = money;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String getMoney() {
return money;
}
public void setMoney(String money) {
this.money = money;
}
}
三、再定义json解析类,我写的后台返回的数据类型分别是code、message、data[],为了方便不同的请求,我把data定义成泛型,如用户类传入user,评论类传入comment
public class ResultData {
private int code;
private String message;
private T[] data;
public T[] getData() {
return data;
}
public void setData(T[] data) {
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
四、定义个UserHttp类处理用户类的请求和请求返回数据的处理,如需处理其他数据类型的请求只需将User改为你要处理的数据类型即可,UserHttp 作为MVP中的P的功能,定义一个接口HttpResult 接口作为C和P的交互
public class UserHttp implements GetInfo>{
private HttpResult httpResult;
public UserHttp(HttpResult httpResult) {
this.httpResult = httpResult;
}
/**
* 注册
* @param user 用户数据
*/
public void CallReg(User user) {
RxJavaRetrofitTool> rxJavaRetrofitTool=new RxJavaRetrofitTool<>(this);
Observable> observable1;
observable1 = rxJavaRetrofitTool.getRequestInterface().getCallReg
(user.getPhone(), user.getPassword(), user.getIdCard(), user.getMoney(), user.getName());
// demo(observable1);
rxJavaRetrofitTool.GetHttpResult(observable1);
}
/**
* 登录
* @param phone 手机号码
* @param password 密码
*/
public void CallLogin(String phone,String password) {
RxJavaRetrofitTool> rxJavaRetrofitTool=new RxJavaRetrofitTool<>(this);
Observable> observable1;
observable1 = rxJavaRetrofitTool.getRequestInterface().getCallLogin(phone,password);
// demo(observable1);
rxJavaRetrofitTool.GetHttpResult(observable1);
}
/**
* http请求成功返回的数据处理
* @param objects ResultData对象实例
*/
@Override
public void Data(ResultData objects) {
//判断登录是否成功
if(objects.getCode()!= Constant.CODE_ERROR)
//传回给activity,只传回user数据的list,其他类型也一样
httpResult.success(Arrays.asList(objects.getData()));
//返回登录失败原因
else httpResult.error(Constant.DATA_NULL);
}
/**
* 网络请求失败
*/
@Override
public void Error() {
//传回给activity
httpResult.error(Constant.OPERATION_ERROR);
}
}
HttpResult.java,同样定义个泛型,方便不同数据类型公用
public interface HttpResult {
void success(List list);//请求成功返回
void error(String code);//请求失败返回
}
五、下面是MVP的M层的处理,我们使用Retrofit这个框架,定义一个接口作为请求接口实现类,Retrofit采用注解的方式非常方便。
public interface GetRequestInterface {
/**
* 注册请求
*
* @param phone 手机号码
* @param password 密码
* @param idCard 身份证号码
* @param money 余额
* @param name 昵称
* @return json
*/
@GET("register?")
Observable> getCallReg(@Query("phone") String phone,
@Query("password") String password,
@Query("idCard") String idCard,
@Query("money") String money,
@Query("name") String name);
@GET("login?")
Observable> getCallLogin(@Query("phone") String phone,
@Query("password") String password);
}
请求处理类RxJavaRetrofitTool,同样是一个泛型,用户只需传入需要请求的Observable类和返回的数据类型即可
import android.util.Log;
import com.andrem.gute.hotel.info.Constant;
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RxJavaRetrofitTool {
private GetInfo getInfo;
public RxJavaRetrofitTool(GetInfo getInfo) {
this.getInfo = getInfo;
}
public GetRequestInterface getRequestInterface(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constant.URL) // 设置 Url
.addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 设置支持RxJava
.build();
// 步骤2:创建 网络请求接口 的实例
return retrofit.create(GetRequestInterface.class);
}
public void GetHttpResult(Observable observable1) {
// 步骤1:创建Retrofit对象
// 步骤3:采用Observable<...>形式 对 2个网络请求 进行封装
//observable1 = request.getCall();
observable1.subscribeOn(Schedulers.io()) // (初始被观察者)切换到IO线程进行网络请求1
.observeOn(AndroidSchedulers.mainThread()) // (新观察者)切换到主线程 处理网络请求1的结果
.subscribe(new Consumer() {
@Override
public void accept(T resultData) throws Exception {
// Log.e("ABD", "accept: " + resultData.getMessage());
//getInfo.Data(Arrays.asList(resultData.getData()));
getInfo.Data(resultData);
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d("ABD", "accept: " + "请求失败");
getInfo.Error();
}
});
}
}
定义接口GetInfo用于M和P层的数据交互,同样定义个泛型,方便不同数据类型公用
public interface GetInfo {
void Data(T objects);//请求成功返回
void Error();//请求失败调用
}
六、上面写完了P和M层,下面就是C层的调用,封装好就很简单了
//调用登录接口,传入phone和password进行网络请求并返回
new UserHttp(new HttpResult() {
@Override
public void success(List list) {
showSnackbar(v,"登录成功");
}
@Override
public void error(String code) {
showSnackbar(v,"登录失败 :"+code);
}
}).CallLogin(phone,passwords);
总结:通过这个这次学习,学习了不少MVP的知识,了解了Retrofit和Rxjava框架的使用,收益匪浅。
问题:UserHttp类只能进行user类的处理,如需处理其他数据类型的话又需定义另外一个类进行处理。目前还找不到整合成一个类的方法,用来处理不同数据类型的网络请求。