优雅地封装使用rxjava2+retrofit2发送http请求
来源:互联网 发布:淘宝售假被扣24分 编辑:程序博客网 时间:2024/06/14 21:58
优雅地封装使用rxjava2+retrofit2发送http请求
一、需要添加的包
implementation 'io.reactivex.rxjava2:rxjava:2.1.6'implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'implementation 'com.squareup.retrofit2:retrofit:2.3.0'implementation 'com.squareup.retrofit2:converter-gson:2.3.0'implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'implementation 'com.google.code.gson:gson:2.8.2'
二、服务器返回的数据格式封装model
1、这里因为返回的实际有效数据Data可能是不确定的数据类型,所以用泛型,使用时指定具体类型。
2、@SerializedName(value = “Status”, alternate = {“status”}),是在Gson把json数据转换的时候对应key的名称,这里的意思是把json中Status或者status都识别为T data。
3、ResultError是另外一个错误信息实体类。
package cn.syninfo.carwork.model;import com.google.gson.annotations.SerializedName;/** * Created by CHHUANG on 2017/11/2. */public class ResultData<T> { @SerializedName(value = "Status", alternate = {"status"}) private boolean status; @SerializedName(value = "Data", alternate = {"data"}) private T data; @SerializedName(value = "Count", alternate = {"count"}) private Integer count; @SerializedName(value = "Error", alternate = {"error"}) private ResultError error; public ResultData(boolean status, T data, Integer count, ResultError error) { this.status = status; this.data = data; this.count = count; this.error = error; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } public T getData() { return data; } public void setData(T data) { this.data = data; } public ResultError getError() { return error; } public void setError(ResultError error) { this.error = error; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } @Override public String toString() { return "ResultData{" + "status=" + status + ", data=" + data + ", count=" + count + ", error=" + (error==null?error:error.toString()) + '}'; }}
返回错误信息实体类
package cn.syninfo.carwork.model;import com.google.gson.Gson;import com.google.gson.JsonArray;import com.google.gson.JsonObject;import com.google.gson.annotations.SerializedName;import java.util.List;/** * Created by CHHUANG on 2017/11/2. */public class ResultError { @SerializedName(value = "Code", alternate = {"code"}) private Integer code; @SerializedName(value = "Message", alternate = {"message"}) private String message; @SerializedName(value = "MessageDetail", alternate = {"messageDetail"}) private String messageDetail; @SerializedName(value = "ModelState", alternate = {"modelState"}) private List<JsonObject> modelState; public ResultError(Integer code, String message, String messageDetail, List<JsonObject> modelState) { this.code = code; this.message = message; this.messageDetail = messageDetail; this.modelState = modelState; } public Integer getCode() { return code; } public String getMessage() { return message; } public String getMessageDetail() { return messageDetail; } public void setCode(Integer code) { this.code = code; } public void setMessage(String message) { this.message = message; } public void setMessageDetail(String messageDetail) { this.messageDetail = messageDetail; } public List<JsonObject> getModelState() { return modelState; } public void setModelState(List<JsonObject> modelState) { this.modelState = modelState; } @Override public String toString() { return "ResultError{" + "code='" + code + '\'' + ", message='" + message + '\'' + ", messageDetail='" + messageDetail + '\'' + ", modelState=" + (modelState==null?modelState:modelState.toString()) + '}'; }}
三、封装Retrofit.Builder,同时创建http请求接口
package cn.syninfo.carwork.service;import retrofit2.Retrofit;import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;import retrofit2.converter.gson.GsonConverterFactory;/** * Created by CHHUANG on 2017/11/2. */public class AppRequest { private AppRequest(){} private static final String BASE_URL = "http://127.0.0.1:8080/";//这里最后一定要有一个/ private Retrofit retrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) //.addCallAdapterFactory(RxJavaCallAdapterFactory.create())//配置rxjava .addCallAdapterFactory(RxJava2CallAdapterFactory.create())// 针对rxjava2.x .baseUrl(BASE_URL) .build(); private AppService service = retrofit.create(AppService.class); private static AppRequest instance; public static synchronized AppRequest getInstance(){ if(instance == null) instance = new AppRequest(); return instance; } public AppService getService() { return service; }}
http请求接口
1、@POST(“User/Login”)//服务器请求地址
2、Flowable
package cn.syninfo.carwork.service;import cn.syninfo.carwork.model.ResultData;import io.reactivex.Flowable;import io.reactivex.Observable;import retrofit2.http.Field;import retrofit2.http.FormUrlEncoded;import retrofit2.http.POST;/** * Created by CHHUANG on 2017/11/2. */public interface AppService { /** * 登录 * //使用@Field模仿表单提交时需要加了@FormUrlEncoded, * //@Query请求参数。无论是GET或POST的参数都可以用它来实现 * @param username * @param password * @return */ @FormUrlEncoded @POST("User/Login")//服务器地址 Flowable<ResultData<String>> login(@Field("LoginName") String username, @Field("LoginPwd") String password);}
四、封装rxjava构成compose,一般情况下的请求都可以用。
1、NetWorkUtils.isNetworkConnected(context),这个方法是用来判断是否有网络,放在doOnSubscribe中,会在执行subscribe方法前执行
2、这里要用FlowableTransformer,因为用了rxjava2的Flowable
package cn.syninfo.carwork.service;import android.content.Context;import android.widget.Toast;import org.reactivestreams.Publisher;import org.reactivestreams.Subscription;import cn.syninfo.carwork.R;import cn.syninfo.carwork.utils.NetWorkUtils;import io.reactivex.Flowable;import io.reactivex.FlowableTransformer;import io.reactivex.android.schedulers.AndroidSchedulers;import io.reactivex.functions.Consumer;import io.reactivex.schedulers.Schedulers;/** * Created by CHHUANG on 2017/11/29. */public class ServiceRxSchedulers { public static <T> FlowableTransformer<T, T> compose(final Context context) { return new FlowableTransformer<T, T>() { @Override public Publisher<T> apply(Flowable<T> upstream) { return upstream.subscribeOn(Schedulers.io()) .doOnSubscribe(new Consumer<Subscription>() { @Override public void accept(Subscription subscription) throws Exception { if (!NetWorkUtils.isNetworkConnected(context)) {//没有网络 Toast.makeText(context, R.string.bad_network, Toast.LENGTH_SHORT).show(); } } }).observeOn(AndroidSchedulers.mainThread()); } }; }}
五、实现FlowableSubscriber,封装预处理,处理掉可以公共处理的部分,留下ResultData中的data部分给调用端处理,只留下onHandleSuccess方法在new的时候实现它。
package cn.syninfo.carwork.service;import android.content.Context;import android.util.Log;import android.widget.Toast;import com.google.gson.JsonObject;import org.reactivestreams.Subscription;import java.util.List;import cn.syninfo.carwork.model.ResultData;import cn.syninfo.carwork.model.ResultError;import io.reactivex.FlowableSubscriber;/** * Created by CHHUANG on 2017/11/29. */public abstract class ServiceSubscriber<T> implements FlowableSubscriber<ResultData<T>> { private static final String TAG = "BaseObserver"; private Context mContext; public ServiceSubscriber(Context context) { this.mContext = context.getApplicationContext(); } @Override public void onSubscribe(Subscription s) { s.request(2);//这里一定要写,估计一般情况上大于0就可以了 } @Override public void onNext(ResultData<T> resultData) { if (resultData.isStatus()) { T t = resultData.getData(); onHandleSuccess(t); } else { onHandleError(resultData.getError()); } } @Override public void onError(Throwable e) { Log.e(TAG, "error:" + e.toString()); } @Override public void onComplete() { Log.d(TAG, "onComplete"); } protected abstract void onHandleSuccess(T t); protected void onHandleError(ResultError error) { Toast.makeText(mContext, error.getMessage(), Toast.LENGTH_SHORT).show(); if(error.getCode()==-1){ List<JsonObject> errors = error.getModelState(); if(errors!=null && !errors.isEmpty()){ for (JsonObject json : errors){ Log.i(TAG, "onHandleError: "+json.getAsString()); } } } }}
六、最后调用
下面代码是在fragment中调用的,parentActivity是在getActivity()方法赋值过的全局变量。
//这里new ServiceSubscriber不能写在subscribe()方法中,不然在android studio中会报错。ServiceSubscriber serviceSubscriber = new ServiceSubscriber<String>(parentActivity) { @Override protected void onHandleSuccess(String token) {//登录成功 Log.i(TAG, "onNext: 令牌="+token); //保存token //登录成功打开fragment_main getFragmentManager().beginTransaction().replace(R.id.main_body, new MainFragment()).commit(); parentActivity.setTitle(R.string.app_name); }};AppRequest.getInstance().getService().login(username, password) .compose(ServiceRxSchedulers.compose(parentActivity)) .subscribe(serviceSubscriber);
七、当然如果有特殊情况,比如要用到嵌套或者要用doOnNext等等自己看情况取舍或重写实现。
- 优雅地封装使用rxjava2+retrofit2发送http请求
- RxJava2 + Retrofit2 优雅简洁封装
- Retrofit2+Rxjava2之优雅的封装
- RxJava2+Retrofit2网络请求框架封装及使用
- rxjava2+rxandroid2+retrofit2 封装网络请求
- Retrofit2+Rxjava2网络请求框架的封装
- retrofit2+rxjava2封装解析
- 简单封装retrofit2+rxjava2
- Rxjava2+okhttp3+Retrofit2封装
- Android 优雅的让RxJava2.0+Retrofit2.0结合使用
- Android 优雅的让RxJava2.0+Retrofit2.0结合使用
- RxJava2+Retrofit2实现网络请求和解析封装
- 给你一个原汁原味的Retrofit2+Rxjava2的请求封装
- 简单实现RxJava2+Okhttp+Retrofit2的网络请求框架封装
- RxJava2和Retrofit Http请求的封装
- Mvp+Retrofit2+RxJava2 项目中使用的简洁封装
- Mvp+Retrofit2+RxJava2 项目中使用的简洁封装
- Android使用Retrofit2+RxJava2+MVP封装实现购物车
- python setuptools介绍
- 不可滑动的ViewPager
- PLSQL编程1:PLSQL块的基本格式
- Codeforces Round #306 (Div. 2) E. Brackets in Implications (构造)
- OpenCV图像各向异性滤波
- 优雅地封装使用rxjava2+retrofit2发送http请求
- 汇总一些知名的 JavaScript 开发开源项目
- 64位Windows 7 安装配置CUDA7.5/8.0+cuDNN5.0
- linux系统常用命令集
- 一个数组队列的实现
- 接口与接口回调
- 微信图片上传接口问题
- Parameter 'phone' not found. Available parameters are [0, 1, param1, param2]关于mybatis多个参数问题
- TabLayout的使用及注意事项(背景色+文字的大小)