基于Retrofit + RxJava的http请求的封装

最近retrofit + RxJava 请求方式很火啊,本人也对此做了一些封装,也算是对架构的一点实践吧,需要文件如下:

‘HttpService接口 定义每个接口

 HttpManager类 处理每个请求

 OperResponse类 接口返回的根结构(基于json格式)

 BaseOperation类 每一个请求的基类


Retrofit + RxJava请求方式需要这样的一个接口,定义方式如下:

public interface HttpService {

    @FormUrlEncoded //采用模拟表单方式请求
    @POST("user/login/v2")//post请求方式,接口名称
    Observable<OperResponse> login(@FieldMap Map<String, String> map);//参数是map集合,发送请求时转换成json发送给服务端
}
 
接下来是HttpManger的定义:
 
public class HttpManager {


    public volatile static HttpManager instance;

    public HttpService httpService;
    private NetWorkUtils netWorkUtils;

    private HttpManager() {
        //手动创建一个okhttpClient并设置超时时间
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
                .connectTimeout(Config.DEFAULT_CONNECTION_TIMEOUT, TimeUnit.SECONDS)//设置连接超时
                .readTimeout(Config.DEFAULT_READ_TIMEOUT, TimeUnit.SECONDS)//设置读超时
                .writeTimeout(Config.DEFAULT_READ_TIMEOUT, TimeUnit.SECONDS)//设置写超时
                .retryOnConnectionFailure(false);//不可重试
        clientBuilder
                .setLevel(Level.BODY)
                .log(Platform.INFO)
                .request("Request")
                .response("Response")
                .addHeader("version", "latest")
                .build());
        OkHttpClient client = clientBuilder.build();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(Config.ROOT_URL)
                .addConverterFactory(GsonConverterFactory.create())//设置参数以及返回数据都是json格式
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//采用RxJava的方式进行请求
                .client(client)//设置客户端
                .build();
        httpService = retrofit.create(HttpService.class);//生成httpService对象

    }

    public static HttpManager getInstance() {
        if (instance == null) {
            instance = new HttpManager();
        }
        return instance;
    }


    /**
     * 用于activity请求
     *
     * @param operation
     * @param context
     */
    public void dealHttpResponse(Context context, BaseOperation operation) {
        if (hasNetwork(context)) {
            if (operation != null) {
                operation.handleError(operation.getNoNetResponse());
            }
            return;
        }
        Observable observable = operation.getObservable(httpService)
                .filter(operation.getFilterFunc1())//过滤返回的数据,如果错误直接处理
                .map(operation.getMapFun1())//转换对象如OperResponse转换成User
                .subscribeOn(Schedulers.io())//子线程进行
                .compose(((RxAppCompatActivity) context).bindToLifecycle())//与activity周期绑定,act销毁则请求结束,activity必须继承RxAppCompatActivity
                .observeOn(AndroidSchedulers.mainThread());//转回主线程
        observable.subscribe(operation.getSubscriber());//处理数据并结束
    }

    /**
     * 用于service等非Activity中请求
     *
     * @param operation
     * @return
     */
    public Subscription dealHttpResponse(BaseOperation operation, Context context) {
        if (hasNetwork(context)) {
            return null;
        }
        Observable observable = operation.getObservable(httpService)
                .filter(operation.getFilterFunc1())
                .map(operation.getMapFun1())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
        return observable.subscribe(operation.getSubscriber());
    }
    private boolean hasNetwork(Context context) {
        netWorkUtils = NetWorkUtils.getNetWorkUtils(context);
        return netWorkUtils.getConnectState().equals(NetWorkUtils.NetWorkState.NONE);
    }
}

 
再就是OperResponse类,因为此封装是基于json格式,如:
public class OperResponse implements Parcelable {
    public String respcode;// code,200表示返回成功
    public String respmsg;// 响应消息
    public String data;// 响应的具体的json数据
   


    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.respcode);
        dest.writeString(this.respmsg);
        dest.writeString(this.data);
       
    }

    public OperResponse() {
    }

    protected OperResponse(Parcel in) {
        this.respcode = in.readString();
        this.respmsg = in.readString();
        this.data = in.readString();
       
    }

    public static final Creator<OperResponse> CREATOR = new Creator<OperResponse>() {
        @Override
        public OperResponse createFromParcel(Parcel source) {
            return new OperResponse(source);
        }

        @Override
        public OperResponse[] newArray(int size) {
            return new OperResponse[size];
        }
    };
}
接下来最重要的类来了,那就是BaseOperation类,是个抽象类,基于solid架构原则,这个类必须是一个抽象类,如下:
 
public abstract class BaseOperation<T> {

    protected RequestListener requestListener;
    protected Context mContext;

    public BaseOperation(Context context, RequestListener requestListener) {
        this.requestListener = requestListener;
        this.mContext = context;
    }

    //获取请求接口
    public abstract Observable getObservable(HttpService httpService);

    //处理返回的数据
    public abstract Subscriber<T> getSubscriber();
    //处理具体的类型,如response->User等等
    public abstract Func1<OperResponse, T> getMapFun1();
    //设置个性化的参数
    protected abstract Map<String, String> setParam();
    //设置共型的参数
    protected Map<String, String> getParam() {
        Map<String, String> map = new HashMap<>();
        map.put(Config.RequestParam.REQUEST_PARAM_VERSION, Config.VERSION_INTERFACE);
        map.put(Config.RequestParam.REQUEST_PARAM_SYSTEM, Config.SYSTEM);
        map.put(Config.RequestParam.REQUEST_PARAM_APP_VERSION, Util.getAppVersionName(mContext));
        map.put(Config.RequestParam.REQUEST_PARAM_OS_VERSION, android.os.Build.VERSION.SDK_INT + "");
        Map<String, String> otherParams = setParam();
        if (otherParams != null && !otherParams.isEmpty()) {
            map.putAll(otherParams);
        }
//        //发送日志记录
//        String content = JsonUtils.requestObjectBean(map);
//        LogManager.getInstance().sendLog(mContext.getApplicationContext(),content);
        return map;
    }

    public Func1<OperResponse, Boolean> getFilterFunc1() {
        return new Func1<OperResponse, Boolean>() {
            @Override
            public Boolean call(OperResponse operResponse) {
                return filerData(operResponse);
            }
        };
    }

    //过滤返回结果,right or wrong
    private boolean filerData(OperResponse operResponse) {
        //发送日志记录
//        String content =  JsonUtils.requestObjectNullBean(operResponse);
//        LogManager.getInstance().sendLog(mContext.getApplicationContext(),content);
        //end
        if (TextUtils.equals(operResponse.respcode, Config.RequestCode.CODE_SUCCESS)) {
            //请求成功
            return true;
        } else {
            handleError(operResponse);
            return false;
        }
    }

    //处理错误结果
    public void handleError(OperResponse operResponse) {
        if (operResponse == null) {
            operResponse = getOperResponse();
        }
        Observable.just(operResponse)
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<OperResponse>() {
                    @Override
                    public void call(OperResponse operResponse) {
                        if (TextUtils.equals(operResponse.respcode, Config.RequestCode.CODE_ERROR_LOGIN_OVERDUE)) {
                            /**
                             * 这两个状态表示登录已过期,跳转到登录页面重新登录
                             */
                            Intent intent = new Intent(mContext, LoginActivity.class);
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            mContext.startActivity(intent);
                        } else {
                            if (requestListener != null) {
                                requestListener.onFailure(operResponse);
                            }
                        }
                    }
                });
    }

    public OperResponse getNoNetResponse(){
        OperResponse operResponse = new OperResponse();
        operResponse.respcode = "104";
        operResponse.respmsg = "无网络连接,请连接网络";
        return operResponse;
    }

    protected OperResponse getOperResponse() {
        OperResponse operResponse = new OperResponse();
        operResponse.respcode = "1000";
        operResponse.respmsg = "网络连接超时,请重试。";
        return operResponse;
    }

    protected OperResponse getParseOperResponse() {
        OperResponse operResponse = new OperResponse();
        operResponse.respcode = "110";
        operResponse.respmsg = "解析数据错误";
        return operResponse;
    }
}
public interface RequestListener<T> {

    void onSuccess(T t);
    void onFailure(OperResponse operResponse);
}

这个类的注释写的也比较清楚,就不过多介绍了,详细介绍一下抽象方法吧,因为在HttpManager中发送请求时是要传入具体的实现类的,比如:LoginOperation,它必须继承BaseOperation类,那么这个抽象类到具体类时,那些会发生变化的方法是要被做成抽象方法的,如使用的每个接口,返回的数据不同等等,都要求方法被抽象化,实际上是使用具体子类的方法返回的数据。
下面是具体使用,此种方式的缺点就是每一个请求都需要一个具体的BaseOperation子类,如登录
public class LoginOperation extends BaseOperation<User>{
private String phoneNumber;
private String password;

public LoginOperation(Context context, RequestListener requestListener) {
    super(context, requestListener);
}

public LoginOperation(Context context, RequestListener requestListener, String phoneNumber, String password) {
    this(context, requestListener);
    this.phoneNumber = phoneNumber;
    this.password = password;
}
@Override
public Observable getObservable(HttpService httpService) {
    return httpService.login(getParam());
}
/**
 * 设置参数
 *
 * @return
 */
@Override
public Map<String, String> setParam() {
    Map<String, String> map = new HashMap<>();
    try {
        String json = JsonUtils.requestObjectBean(new RegisterVoBean.RegisterObj(phoneNumber, password));
        map.put("para", data);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return map;
}
@Override
public Subscriber<User> getSubscriber() {
    return new Subscriber<User>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {
            if (requestListener != null)
                requestListener.onFailure(getOperResponse());
        }

        @Override
        public void onNext(User user) {
            if (userResult != null)
                requestListener.onSuccess(user);
        }
    };
}
    @Override
    public Func1<OperResponse, User> getMapFun1() {
        return new Func1<OperResponse, User>() {
            @Override
            public User call(OperResponse operResponse) {
                User user = null;
                try {
                    user = JsonUtils.parserJsonStringToObject(operResponse.data, User.class);
 
                } catch (Exception e) {
                    //处理异常,json转object错误
//                    handleError(operResponse);
                    e.printStackTrace();
                }
                return user;
            }
        };
    }
 }
 
 
最后在来个门面模式包装一下
public class OperateFactoryManager {

    private static OperateFactoryManager instance;

    private OperateFactoryManager() {

    }

    public static OperateFactoryManager getInstance() {
        if (instance == null) {
            instance = new OperateFactoryManager();
        }
        return instance;
    }
/**
 * 登录
 *
 * @param context
 * @param phoneNumber
 * @param verifyCode
 * @param requestListener
 */
public void login(Context context, String phoneNumber, String password, RequestListener requestListener) {
    LoginOperation loginOperation = new LoginOperation(context, requestListener, phoneNumber, password);
    HttpManager.getInstance().dealHttpResponse(context, loginOperation);
}

}
需要的jar如下:
compile 'io.reactivex:rxandroid:1.2.1'
//RxAndroid
compile 'io.reactivex:rxjava:1.1.6'
//RxJava
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0'
compile 'com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0'
compile 'com.jakewharton.rxbinding:rxbinding-appcompat-v7:0.4.0'
compile 'com.trello:rxlifecycle-android:0.8.0'
compile 'com.trello:rxlifecycle-components:0.8.0'
compile 'com.trello:rxlifecycle:0.8.0'
compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'

 
以上就是我对Retofit+RxJava做的一个简单的封装,还可以对上传和下载也进行这样的封装,这里就不一一介绍了,感兴趣的同学可以看看,如果有更好建议,欢迎交流哈。
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值