2016-04-07 9 views
6

Prima di utilizzare rx.Observable, ho utilizzato una richiamata personalizzata con aggiornamento, in modo da poter aggiungere una logica specifica per la gestione della risposta/errore e non dover eseguire questa operazione all'interno della richiamata per ogni richiesta come codice boilerplate.RxJava/Retrofit - Come posso costringere gli utenti a utilizzare una sottoclasse specifica di Sottoscrittore?

ho obbligare gli utenti a utilizzare il callback personalizzato mettendolo nella firma del metodo come questo:

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

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

ma ora che sto tornando un Observable:

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

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

non posso trovare un modo per assicurarsi che una richiamata personalizzata risponda sempre all'errore/risposta.

Inoltre, con retrofit2.0, come posso forzare l'utente a utilizzare una richiamata personalizzata con l'oggetto Call restituito?

CustomCallback per riferimento:

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); 
} 
+0

Le domande sono: perché è necessario restituire un osservabile, quando non si è in grado di utilizzare solo qualche osservabile? Perché non rendere CustomCallback estendibile e quindi restituirlo come tipo? Quando dici che vuoi essere sicuro che trasmetta la risposta, dove vuoi delegarlo, agli osservatori? –

+0

il tipo restituito deve essere un rx.Observable, non una sottoclasse https://github.com/square/retrofit/blob/parent-1.4.0/retrofit/src/main/java/retrofit/RestAdapter.java#L244 – Prem

risposta

-1

Stop. Stai pensando questo nel modo sbagliato.

considerare invece questo: Hai la normale interfaccia di Retrofit:

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

E poi ci sono la classe decoratore:

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

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

Poi si usa solo la seconda classe ovunque nel codice (preferibilmente lascia che sia il sistema DI a usarlo) e sei pronto.

Se ti senti avventuroso, puoi anche adattare lo RxJavaCallAdapterFactory in modo da modificare le osservabili restituite senza la necessità di una classe personalizzata.

+0

So che la creazione di una classe decoratore funzionerà ma richiede l'implementazione di ogni metodo con la stessa logica. Stavo cercando una soluzione più pulita. E 'RxJavaCallAdapterFactory' https://github.com/square/retrofit/blob/master/retrofit-adapters/rxjava/src/main/java/retrofit2/adapter/rxjava/RxJavaCallAdapterFactory.java è una classe finale quindi dovrei usare la mia forcella di retrofit che non è la soluzione che stavo cercando – Prem

+0

Se vuoi, puoi usare un 'java.lang.reflext.Proxy' per eseguire il wrapping, quindi non hai bisogno di una classe esplicita. –

Problemi correlati