通用方法来处理所有Web服务调用的响应和错误

时间:2018-07-05 10:57:19

标签: android rx-java2

我正在尝试创建通用化方法来处理以下问题

  1. 来自网络服务的响应
  2. 处理HTTP错误和自定义错误

为此,我编写了以下代码并创建了回调来处理响应ResponseCallback和错误ErrorCallback

要获取与营养或其他任何物体有关的数据,我可以使用相同的回调。

    Request request = new Request();
    request.setAccess_token("d80fa6bd6f78cc704104d61146c599bc94b82ca225349ee68762fc6c70d2dcf0");
    request.setStart_date("2018-06-01T00:00:00");
    Flowable<Response> fitnessFlowable = new WebRequest()
            .getRemoteClient()
            .create(FitnessApi.class)
            .getFitnessData("5b238abb4d3590001d9b94a8",request.toMap());

      fitnessFlowable.subscribeOn(Schedulers.io())
            .takeUntil(response->response.getSummary().getNext()!=null)
            .doOnNext(new ResponseCallback())
            .doOnError(new ErrorCallback<Throwable>())
            .subscribe();

响应回调

public  class ResponseCallback<T extends Response> implements Consumer<Response> {


    @Override
    public void accept(Response response) throws Exception {
        if(response ==null || response.getFitness() == null || response.getFitness().isEmpty()) {


            new Exception("NUll response");

        }

        RxBus.getInstance().send(response.getFitness());
       Log.e("Data","accept");
        try(Realm r = Realm.getDefaultInstance()) {
            r.executeTransaction((realm) -> {
                realm.copyToRealmOrUpdate(response.getFitness());
            });
        }
    }
}

错误回调

public class ErrorCallback <T extends Throwable> implements Consumer<Throwable> {

    public static final String TAG = "ErrorCallback";
    @Override
    public void accept(Throwable e) throws Exception {

        if (e instanceof HttpException) {
            ResponseBody body = ((HttpException) e).response().errorBody();
            try {
                Response response=  LoganSquare.parse(body.byteStream(),Response.class);

                if(response.getErrors() !=null)
                    if(response.getErrors().size() > 0)
                      Log.e(TAG , response.getErrors().get(0).getErrors() );

            } catch (IOException t) {
                t.printStackTrace();
            }

        } else if (e instanceof SocketTimeoutException) {

            Log.e(TAG , e.getMessage() );

        }else if (e instanceof IOException) {

            Log.e(TAG , e.getMessage() );
        }else{
            Log.e(TAG , e.getMessage() );
        }
    }
}

这里我要解决两个问题

  1. 要处理响应和错误,我需要进行两个单独的回调。还有什么其他方法可以处理回调中的响应和错误,而不是创建两个单独的

  2. 我什么时候应该在上面的代码中处理订阅,因为您可以在我的代码中看到我的订阅陷入困境。

我已经引荐this link设计一般化方法。

1 个答案:

答案 0 :(得分:1)

解决问题#1 -

  

要处理响应和错误,我需要进行两个单独的回调。是   还有其他方法可以处理回调中的响应和错误   而不是创建两个单独的

在“干净架构”方法中,您的Web服务将被定义为RemoteDataSource(可能遵循“ DataSource”协议。RemoteDataSource应该将其序列化为类格式-如果您能够使用Kotlin,则{ 3}}是一个很好的选择(如果Kotlin不是-:(-,然后查看Enums或IntDefs)。请参见以下内容:

/**
 * The return state from the Data Layer
 */
sealed class ServiceResult {

    data class Success(val list: List<MySerializedObject>) : ServiceResult()

    data class Error(val reason: Throwable?) : ServiceResult()
}

这使您可以将单个状态从数据层备份,通过域层(您可以根据结果执行其他逻辑),最后传递到视图层,演示者可以在此打开该状态这样:

  when (result) {
                    is ServiceResult.Success -> {
                        serializeToViewModel(result) // VM to the Adapter
                    }
                    is ServiceResult.Error -> result.reason?.let {
                        PartialViewState.Error(it) // Can be rendered immediately
                    } 
                }

您的演示者然后可以在视图上调用render方法,如下所示:

            ... subscribeOn() etc
            .subscribe({ view?.render(it) }, { view?.render(ViewState(error = it)) })

然后,您的视图的render方法可以在切换要呈现的视图状态,显示的错误消息等之间执行少量逻辑。

仅供参考,我使用的体系结构在很大程度上取决于sealed class ...我强烈推荐它。