2017-08-01 41 views
2

我一直在使用MVP體系結構,使用Retrofitcallbacks一段時間。我想用RxJava/Android取代我的回調,但我似乎無法理解應該如何完成。使用RxAndroid MVP Retrofit修改回調

我對攔截器(交互器)的接口:

public interface FoodInterceptor extends MvpInterceptor { 
    /*void getFoodList(RestCallback<FoodListResponse> callback);*/ 

    Observable getFoodList(Consumer<FoodListResponse> foodListResponseConsumer, Consumer<Throwable> error); 
} 

然後是攔截器實現:

public class FoodInterceptorImpl implements FoodInterceptor { 

    @Inject 
    ApiService mApiService; 
    @Inject 
    ErrorUtils mErrorUtils; 
    @Inject 
    SchedulerProvider mSchedulerProvider; 
    @Inject 
    CompositeDisposable mCompositeDisposable; 

    @Inject 
    public FoodInterceptorImpl() { 
     super(); 
    } 

    @Override 
public Observable<FoodListResponse> getFoodList(Consumer<FoodListResponse> foodListResponseConsumer, Consumer<Throwable> throwable) { 
    mApiService.getFoodList() 
      .subscribeOn(mSchedulerProvider.backgroundThread()) 
      .observeOn(mSchedulerProvider.mainThread()) 
      .subscribe(foodListResponse -> Log.d("TAG", "FoodResponse: " + foodListResponse), 
        throwable1 -> Log.d("TAG", "Throwable: " + throwable)); 

    return ?; 
} 

    @Override 
    public void unbind() { 

    } 

    /*@Override 
    public void getFoodList(final RestCallback<FoodListResponse> callback) { 
     mApiService.getFoodList().enqueue(new Callback<FoodListResponse>() { 
      @Override 
      public void onResponse(Call<FoodListResponse> call, Response<FoodListResponse> response) { 
       if (response.isSuccessful()) { 
        Result<FoodListResponse> result = new Result<>(); 
        FoodListResponse foodListResponse = response.body(); 
        result.setData(foodListResponse); 
        callback.onSuccess(result); 
       } else { 
        mRestError = mErrorUtils.parseResponse(response); 
        Log.d("Test", "Error: " + mRestError.getMessage()); 
       } 

      } 

      @Override 
      public void onFailure(Call<FoodListResponse> call, Throwable t) { 

      } 
     }); 

    }*/ 

    /*@Override 
    public void cleanup() { 

    }*/ 

} 

在註釋掉的代碼,你可以看到我是如何用一個回調做,但Rx要求我退還Observable。我會怎麼做?我如何通知我的發言人數據已被提取?

Presenter的界面:

@PerActivity 
public interface FoodPresenter<V extends FoodView, I extends FoodInterceptor> extends MvpPresenter<V, I> { 
    void renderFoods(); 
} 

而且主講人:

public class FoodPresenterImpl<V extends FoodView, I extends FoodInterceptor> 
     extends BasePresenter<V, I> implements FoodPresenter<V, I> { 

    @Inject 
    public FoodPresenterImpl(I mvpInterceptor, 
          SchedulerProvider schedulerProvider, 
          CompositeDisposable compositeDisposable) { 
     super(mvpInterceptor, schedulerProvider, compositeDisposable); 
    } 



@Override 
public void renderFoods() { 
    getMvpView().showProgress(true); 
    getInterceptor().getFoodList(foodListResponse -> { 
     if (!isViewAttached()) { 
      return; 
     } 
     getMvpView().renderFoods(foodListResponse.getFoodList().getFoodItemList()); 
     getMvpView().showProgress(false); 
    }, throwable -> { 
     if (!isViewAttached()) { 
      return; 
     } 
     getMvpView().showProgress(false); 
    }); 
} 

    /*@Override 
    public void renderFoods() { 
     getMvpView().showProgress(true); 
     getInterceptor().getFoodList(new RestCallback<FoodListResponse>() { 
      @Override 
      public void onSuccess(Result<FoodListResponse> result) { 
       if (!isViewAttached()) { 
        return; 
       } 
       getMvpView().renderFoods(result.getData().getFoodList().getFoodItemList()); 
       getMvpView().showProgress(false); 
      } 

      @Override 
      public void onFailure(RestError error) { 

      } 
     }); 
    }*/ 
} 

回答

0

讓我分解你的邏輯有點:

  1. renderFoods被調用演示者
  2. 主持人呼叫截擊,所以它會獲取api和返回結果
  3. 攔截器調用mApi.getFoodList()(它應返回Observable)並itnterceptro訂閱結果。我會用的λ,所以有可能錯過部分:

    mApi.getFoodList() 
        .subscribeOn(Schedulers.io()) // main work will be on io thread 
        .observeOn(AndroidSchedulers.mainThread()) // result will be passed to main thread 
        .subscribe((result, throwable) -> { 
        // it's like your calback, the job are done 
        // and you get result in result parameter, 
        // and if error occurs, result will be null 
        // and throwable parameter has an cause 
        // so, here you can apply errorUtils on result, check the throwable, 
        // or pass result to your presenter 
        }); 
    

希望它能幫助!

+0

感謝您的回答!但是,如何返回Observable,以及如何將結果傳遞給Presenter而無需回調?我編輯了我的代碼。 – Esteban

+0

您可以在演示者中訂閱並處理請求結果。但是你需要使用map來轉換結果。你在攔截器中的方法將返回'Observable ',並且在這個方法的主體中將返回 'return api.getFoodList()。map(response - > parseResponseAndReturnObjects()) .subscribe(...) .observe (...)' 當你創建'Observable'時,把它們想象成一個流。你可以在流上添加運算符,這會改變數據,比如'map()',其他的會改變像'subscribe()'這樣的線程。但是在你調用'subscribe()'之前它會返回觀察值 –