当Retrofit2+RxJava2遇到为null的返回结果

前言

优雅的写法请直接看最后
更新RxJava2之后,就不能在onNext里面发送null值了。但是项目中有些接口,例如更新用户密码的接口(我就遇到了),后台没有返回数据(也就是null),于是修改密码成功,但是活动crash(没有走onNext方法,而是走onError方法,但是异常对象也是null,提示Null is not a valid element),在网上找到了一片文章当Retrofit2+RxJava2遇到为null的返回结果,但是原谅我没看懂,哭(┬_┬),返回结果还是会走到onError里,我们最终的目的是要返回到onNext里


正题

下面说一下我的解决方法
利用map操作符,把被观察者(null)转换成不为null的任意对象再传递给观察者
问题没有解决之前是这样写的

 public static void updateUserPassword(String oldPwd,String newPwd,Observer<Object> observer){
        ApiSubscribe(RetrofitCreateHelper.getDocServiceApi().updateUserPassword(oldPwd,newPwd),observer);

利用map操作符后是这样写的

/**
  * 修改密码,由于请求返回null,而RxJava2的onNext()方法不允许传入null,所以这里利用map操作符转换被观察者(事件)类型
  * @param oldPwd
  * @param newPwd
  * @param observer
  */
    public static void updateUserPassword(String oldPwd,String newPwd,Observer<String> observer){
        ApiSubscribe(RetrofitCreateHelper.getDocServiceApi().updateUserPassword(oldPwd,newPwd).map(new Function<Object, String>() {
            @Override
            public String apply(Object optional) throws Exception {
                return optional == null? "1":"2";
            }
        }),observer);
    }

下面是更新优雅的写法:

第一步,自定义ConvertFactory

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;

public class NullOrEmptyConvertFactory extends Converter.Factory {

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        final Converter<ResponseBody,?> delegate = retrofit.nextResponseBodyConverter(this,type,annotations);
        return new Converter<ResponseBody, Object>() {
            @Override
            public Object convert(ResponseBody value) throws IOException {
                if (value.contentLength() == 0) return null;
                return delegate.convert(value);
            }
        };
    }
}

第二步:修改接口返回类型

import retrofit2.Response;
@GET("device/code")
Observable<Response<Device>> getDeviceByCode(@Query("code") String code);
//由原来的Observable<Device> 改成 Observable<Response<Device>>

第三步:
在现有的ConvertFactory之前添加自己定义的ConvertFactory

return new Retrofit.Builder()
        .baseUrl(Constant.apiUrl)
        .addConverterFactory(new NullOrEmptyConvertFactory())
        .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().serializeNulls().create()))
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .client(getHttpClient())
        .build();

第四步:对返回结果判断

subscribe(new BaseObserver<Response<Device>>(mContext) {
   @Override
   public void onNext(Response<Device> device) {
       TLog.e("device success");
       if (null == device.body()){
           //如果接口返回成功,但是返回值为null,就会走到这里
       }
   }

第五步完成:提示,如果不修改返回值的话,仍然会走到onError,而不会走到onNext()

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值