RxJava/Retrofit — как заставить пользователей использовать определенный подкласс подписчика?

Перед использованием rx.Observable я использовал пользовательский обратный вызов с модификацией, поэтому я могу добавить определенную логику для обработки ответа/ошибки, и мне не нужно делать это внутри обратного вызова для каждого запроса в виде стандартного кода.

Я заставляю пользователей использовать пользовательский обратный вызов, помещая его в сигнатуру метода следующим образом:

@GET("/user_endpoint/")
void getUser(CustomCallback<User> callback);

@GET("/profile_endpoint/")
void getProfile(CustomCallback<Profile> callback);

но теперь, когда я возвращаю Observable:

@GET("/user_endpoint/")
Observable<User> getUser();

@GET("/profile_endpoint/")
Observable<Profile> getProfile();

Я не могу найти способ убедиться, что пользовательский обратный вызов всегда передает ошибку/ответ.

Кроме того, с Retrofit2.0, как я могу заставить пользователя использовать пользовательский обратный вызов с возвращенным объектом Call?

CustomCallback для справки:

public abstract class CustomCallback<T> implements Callback<T> {

  @Override public final void success(T t, Response response) {
    // do some logic
    onSuccess(t);
  }

  @Override public final void failure(RetrofitError error) {
    // do something with the error here such as show a Toast
    Toast.makeText(Application.getInstance(), error.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
    onFailure(error);
  }

  public abstract void onSuccess(T response);

  public abstract void onFailure(Throwable error);
}

person Prem    schedule 07.04.2016    source источник
comment
Вопрос в том, почему вам нужно возвращать наблюдаемое, если вы, очевидно, не можете использовать любое наблюдаемое? Почему бы не сделать CustomCallback расширением Observable, а затем вернуть это как тип? Когда вы говорите, что хотите убедиться, что он проксирует ответ, куда вы хотите проксировать его, наблюдателям?   -  person Nick Cardoso    schedule 13.04.2016
comment
возвращаемый тип должен быть rx.Observable, а не подклассом github.com/square/retrofit/blob/parent-1.4.0/retrofit/src/main/   -  person Prem    schedule 13.04.2016


Ответы (1)


Останавливаться. Вы думаете об этом неправильно.

Вместо этого рассмотрите следующее: у вас есть обычный интерфейс Retrofit:

interface Foo {
   @GET("/user_endpoint/")
   Observable<User> getUser();
}

И тогда у вас есть класс декоратора:

public class FooDecorator implements Foo {
    private Foo delegate = ...; // inject or create the Retrofit instance.

    @Override
    public Observable<User> getUser() {
       return delegate.getUser().doOnNext(...).doOnError(...);
    }
}

Затем вы используете только второй класс везде в своем коде (предпочтительно просто позволить системе DI использовать его), и все готово.

Если вы чувствуете себя предприимчивым, вы можете даже адаптировать RxJavaCallAdapterFactory так, чтобы он модифицировал возвращаемые наблюдаемые без необходимости использования специального класса.

person Tassos Bassoukos    schedule 07.04.2016
comment
Я знаю, что создание класса декоратора будет работать, но для этого требуется, чтобы вы реализовали каждый метод с одной и той же логикой. Я искал более чистое решение. И RxJavaCallAdapterFactory github.com/square/retrofit/blob/master/retrofit-adapters/rxjava/ — это окончательный класс, поэтому мне придется использовать свою собственную вилку модификации, которая не является решением, которое я искал - person Prem; 08.04.2016
comment
Если вы хотите, вы можете использовать java.lang.reflext.Proxy для переноса, тогда вам не нужен явный класс. - person Tassos Bassoukos; 08.04.2016