Android网络请求框架之Retrofit(二)

前面一篇文章介绍了Retrofit的基本用法,没有看过的童鞋可以移步:Android网络请求框架之Retrofit(一),现在我们来继续介绍Retrofit配合RxJava、RxAndroid的用法。

配合Rx是为了体现函数式编程的思想,其实用法差别不大,只是在接口里定义方法的返回值有所差别,当然,build.gradle文件里需要导入两个库地址

io.reactivex:rxjava:1.0.14 
io.reactivex:rxandroid:1.0.1

下面我们以更新任务为例,观察两种方式的区别

public interface ITask {
    //RX模式的方法定义之一
    @PUT("/task/{Id}")
    Observable<Task> update(@Path("Id") String Id,@Body HashMap<String, Object> body);

    //RX模式的方法定义之二
    @PUT("/task/{Id}")
    Call<Task> _update(@Path("Id") String Id,@Body HashMap<String, Object> body);

    //常规异步式的方法定义
    @PUT("/task/{Id}")
    void update_(@Path("Id") String Id,@Body HashMap<String, Object> body,Callback<Task> callback);
}

方法很容易区别,一个是返回参数在回调接口里,一个是直接返回,但返回的不是最终的对象。

按照常规的调用


                HashMap<String, Object> map = new HashMap<>();
                map.put("title", title);
                map.put("content", content);
                map.put("responsiblePersons", Arrays.asList(new    Reviewer(mTask.getResponsiblePerson())));   
                map.put("members", mTask.getMembers());
                map.put("actualendAt", mTask.getActualEndAt());
                map.put("remindflag", mTask.getRemindTime() > 0);
                map.put("remindtime", mTask.getRemindTime());
                map.put("reworkflag", switch_approve.isChecked());

                if (!TextUtils.isEmpty(mTask.getAttachmentUUId()) && mTask.getAttachments().size() > 0) {
                    map.put("attachmentUUId", mTask.getAttachmentUUId());
                }

                if (!TextUtils.isEmpty(mTask.getProjectId())) {
                    map.put("projectId", mTask.getProjectId());
                }

                RestAdapterFactory.getInstance().build(Config_project.API_URL()).create(ITask.class).update_(mTask.getId(), map,new RCallback<Task> (){
 @overide
    public void success(Task task,Response  r){
         task.setAck(true);
         Toast(getString(R.string.app_add) + getString(R.string.app_succeed));
         Intent intent = new Intent();
         intent.putExtra("data", task);
         setResult(Activity.RESULT_OK, intent);
         onBackPressed();                   
    }
    @Overide
    public void failure(RetrofitError e){
    }
});

这种调用没什么好说的,和前面一篇文章里的一样,服务器返回的结果会封装在RCallback里面,并且回调方法在主线程。

下面我们看看按照Rx模式调用之一


                HashMap<String, Object> map = new HashMap<>();
                map.put("title", title);
                map.put("content", content);
                map.put("responsiblePersons", Arrays.asList(new Reviewer(mTask.getResponsiblePerson())));
                map.put("members", mTask.getMembers());
                map.put("actualendAt", mTask.getActualEndAt());
                map.put("remindflag", mTask.getRemindTime() > 0);
                map.put("remindtime", mTask.getRemindTime());
                map.put("reworkflag", switch_approve.isChecked());

                if (!TextUtils.isEmpty(mTask.getAttachmentUUId()) && mTask.getAttachments().size() > 0) {
                    map.put("attachmentUUId", mTask.getAttachmentUUId());
                }

                if (!TextUtils.isEmpty(mTask.getProjectId())) {
                    map.put("projectId", mTask.getProjectId());
                }

                RestAdapterFactory.getInstance().build(Config_project.API_URL()).create(ITask.class).update(mTask.getId(), map)
                        .observeOn(AndroidSchedulers.mainThread())//指定订阅的线程-主线程
                        .subscribe(new Subscriber<Task>() {//订阅
                            //处理完成
                            @Override
                            public void onCompleted() {

                            }
                            //处理出错
                            @Override
                            public void onError(Throwable e) {
                                e.printStackTrace();
                            }
                            //处理过程
                            @Override
                            public void onNext(Task task) {
                                task.setAck(true);
                                      Toast(getString(R.string.app_add)+getString(R.string.app_succeed));        

                                Intent intent = new Intent();
                                intent.putExtra("data", task);
                                setResult(Activity.RESULT_OK, intent);
                                onBackPressed();
                            }
                        });

在这里,接口定义的方法直接返回了一个Observable对象,指定这个对象发生订阅的线程,然后订阅事件,最后也是异步回调的,不过在这个过程中,我们可以指定回调方法发生的线程,看起来的话onNext方法和success方法其实没啥区别,都带回了我们需要的数据,但是从代码层次上来看,Rx模式的代码逻辑层次更清楚。

下面我们再看看按照Rx模式调用之二

HashMap<String, Object> map = new HashMap<>();
                map.put("title", title);
                map.put("content", content);
                map.put("responsiblePersons", Arrays.asList(new    Reviewer(mTask.getResponsiblePerson())));   
                map.put("members", mTask.getMembers());
                map.put("actualendAt", mTask.getActualEndAt());
                map.put("remindflag", mTask.getRemindTime() > 0);
                map.put("remindtime", mTask.getRemindTime());
                map.put("reworkflag", switch_approve.isChecked());

                if (!TextUtils.isEmpty(mTask.getAttachmentUUId()) && mTask.getAttachments().size() > 0) {
                    map.put("attachmentUUId", mTask.getAttachmentUUId());
                }

                if (!TextUtils.isEmpty(mTask.getProjectId())) {
                    map.put("projectId", mTask.getProjectId());
                }

                RestAdapterFactory.getInstance().build(Config_project.API_URL()).create(ITask.class)._update(mTask.getId(), map).enqueue(new RCallback<Task>() {
                    @Override
                    public void success(Task task) {
                        task.setAck(true);  

                     Toast(getString(R.string.app_add)+getString(R.string.app_succeed));                                                              
                        Intent intent = new Intent();
                        intent.putExtra("data", task);
                        setResult(Activity.RESULT_OK, intent);
                        onBackPressed();
                    }

                    @Override
                    public void onFailure(Throwable error) {

                    }
                });

这里是反回了一个Call对象,调用enqueue的时候就像我们常规模式调用时那样传入callback接口,从里面获取数据。

当然RX模式的好处远不止这一个,比如说,当我们需要显示等待dialog的时候,常规的异步式调用可能就需要我们维护一个progressdialog,但Rx模式就可以很方便的实现。Subscriber有一个空实现的方法onStart,是在开始连接服务器之前调用的,我们可以封装一个commonSubscriber,在 onStart方法里去显示一个progressdialog,在onError或onComplete方法里去自动销毁这个progressdialog。

public abstract class CommonSubscriber extends Subscriber<Serializable> {

    private CustomProgressDialog dialog;

    public CommonSubscriber(Activity context) {
        dialog = new CustomProgressDialog(context);
    }

    @Override
    public void onStart() {
        super.onStart();
        dialog.show();
    }

    @Override
    public void onNext(Serializable serializable) {
        BaseBen baseBen = (BaseBen) serializable;
        if(null!=baseBen) {
            if ((!TextUtils.isEmpty(baseBen.getErrorCode())&&baseBen.getErrorCode().contains( ErrorUtil.ERROR_TOKEN_ERROR)) || ((!(baseBen instanceof TokenInfo)) && null == BusApplication.getInstance().getTokenInfo())) {
                BusApplication.getInstance().backToLogin();
            }
        }
    }

    @Override
    public void onError(Throwable e) {
        dialog.dismiss();
        dialog=null;
    }

    @Override
    public void onCompleted() {
        dialog.dismiss();
        dialog=null;
    }
}

关于Rx相关的知识,我也知道得很有限,有一些比较专业的用法我也不敢信笔涂鸦,有兴趣的小伙伴可以去查阅一下相关的资料,或许就会有更大的发现。比如说可以指定多次observeOn,但是subscribeOn只认可第一次;可以用filter方法过滤调一些返回值,可以用flatMap封装下一步需要的参数等等。

最后我贴出一段我用纯Rx模式实现的请求代码供大家参考

//-------------------------------RxJava实现方式开始--------------------------------
        Observable.just(schedule)
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                        //判断行程是否有效,过滤掉无效行程
                .filter(new Func1<TourSchedule, Boolean>() {
                    @Override
                    public Boolean call(TourSchedule tourSchedule) {
                        if (null == schedule) {
                            ptrFrameLayout.refreshComplete();
                            dialog.dismiss();
                            ToolToast.showShort("车次信息错误,无法获取订单");
                        }
                        return null != schedule;
                    }
                })
                        //网络请求置于IO线程
                .observeOn(Schedulers.io())
                        //先去请求服务器数据
                .flatMap(new Func1<TourSchedule, Observable<CommonListBen<TravelOrderForm>>>() {
                    @Override
                    public Observable<CommonListBen<TravelOrderForm>> call(TourSchedule schedule) {
                        HashMap<String, Object> map = new HashMap<>();
                 map.put("busNoId", schedule.getBusNoId());
                 map.put("busId", schedule.getBusId());
                 map.put("day", schedule.getDay());
                 map.put("planId", schedule.getPlanId());
                        return ServiceGenerator.getInstance().create(IOrderForm.class, BusApplication.getInstance().getToken()).getOrderFormList_(map);
                    }
                })
                        //截获错误,不回调onError方法,使流程继续
                .onErrorReturn(new Func1<Throwable, CommonListBen<TravelOrderForm>>() {
                    @Override
                    public CommonListBen<TravelOrderForm> call(Throwable throwable) {
                        return null;
                    }
                })
                .observeOn(Schedulers.newThread())
                        //请求的结果转换为最终需要的数据
                .map(new Func1<CommonListBen<TravelOrderForm>, ArrayList<TravelOrderForm>>() {
                    @Override
                    public ArrayList<TravelOrderForm> call(CommonListBen<TravelOrderForm> travelOrderFormCommonListBen) {
                        return null == travelOrderFormCommonListBen ? null : travelOrderFormCommonListBen.getData();
                    }
                })
                        //处理服务器返回的数据,混合缓存
                .flatMap(new Func1<ArrayList<TravelOrderForm>, Observable<ArrayList<TravelOrderForm>>>() {
                    @Override
                    public Observable<ArrayList<TravelOrderForm>> call(ArrayList<TravelOrderForm> travelOrderForms) {
                        if (mDao == null)
                            mDao = new TravleOrderFormDao(mContext);
                        //从数据库获取
                        if (null == travelOrderForms) {
                            //需要取存数据,以planId为主键
                            TravelOrderFormData dataDb = mDao.get(schedule.getPlanId());
                            if (null != dataDb) {
                                Gson gson = new Gson();
                                Type type = new TypeToken<ArrayList<TravelOrderForm>>() {
                                }.getType();
                                travelOrderForms = gson.fromJson(dataDb.getJson(), type);
                            }
                        }
                        //存数据库
                        else {
                            TravelOrderFormData data = new TravelOrderFormData();
                            data.setPlanId(schedule.getPlanId());
                            Gson gson = new Gson();
                            data.setJson(gson.toJson(travelOrderForms));
                            mDao.add(data);
                        }
                        return Observable.just(travelOrderForms);
                    }
                })
                        //显示最后获得的结果
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<ArrayList<TravelOrderForm>>() {
                    @Override
                    public void onCompleted() {
                        dialog.dismiss();
                        ptrFrameLayout.refreshComplete();
                    }

                    @Override
                    public void onError(Throwable e) {
                        dialog.dismiss();
                        ptrFrameLayout.refreshComplete();
                    }

                    @Override
                    public void onNext(ArrayList<TravelOrderForm> datas) {
                        travelOrderForms = datas;
                        handleCustomers();
                        dataChange();
                    }
                });
//-------------------------------RxJava实现方式结束--------------------------------
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值