Sto utilizzando la Java più recente RX dove invece dirxJava Android movimentazione con retrofit
Observable.create(new Observable.OnSubscribeFunc<T>() {...});
questo viene utilizzato Errore: (a causa di disapprovazione)
Observable.create(new Observable.OnSubscribe<T>() {...});
(Questo può essere importante come la maggior parte esempio, tutorial, explonation usa quello vecchio ...)
Bene, vediamo il mio problema. Ho una classe Java, parti rilevanti da questa:
private interface ApiManagerService {
@FormUrlEncoded
@POST("/login")
User getUser(@Field("username") String userName, @Field("password") String password);
}
private static RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(HOST)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
private static ApiManagerService apiManager = restAdapter.create(ApiManagerService.class);
public static Subscription login(final String userName, final String password, Observer<User> observer) {
return Observable.create(new Observable.OnSubscribe<User>() {
@Override
public void call(Subscriber<? super User> subscriber) {
try {
User user = apiManager.getUser(userName, password);
subscriber.onNext(user);
subscriber.onCompleted();
} catch (RetrofitError e) {
subscriber.onError(e);
} catch (Throwable e) {
subscriber.onError(e);
}
}
}
).subscribeOn(Schedulers.io())
.retry(3)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(observer);
}
Questo codice funziona quasi perfettamente, se tutto è ok. Ma se faccio un errore intenzionale, come quando spengo il WiFi .. che il retrofit, ottieni il "UnKnownHostException" ... come dovrebbe accadere alla chiamata di aggiornamento (getUser) nel blocco catch try. Ma invece di gestire l'errore su onError (Throwable t) -> dove posso gestire, si blocca semplicemente l'app. Quindi è come se l'errore non arrivasse mai al blocco catch. Ciò che è strano è che errori HTTP (come 404, 401 ecc.) Vengono catturati, ottenuti da onError (...) e tutto va bene.
Tutto va per 3 volte prima del crash, a partire da .retry (3) ma nessuno entra in catch clausola.
EDIT 1
LogCat uscita:
01-08 16:19:31.576 15285-16162/asd.bdef.gh D/Retrofit﹕ ---- ERROR https://testapi.com/api/login
01-08 16:19:31.606 15285-16162/asd.bdef.gh D/Retrofit﹕ java.net.UnknownHostException: Unable to resolve host "testapi.com": No address associated with hostname
at java.net.InetAddress.lookupHostByName(InetAddress.java:394)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at com.squareup.okhttp.internal.Network$1.resolveInetAddresses(Network.java:29)
at com.squareup.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:259)
at com.squareup.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:233)
at com.squareup.okhttp.internal.http.RouteSelector.nextUnconnected(RouteSelector.java:159)
at com.squareup.okhttp.internal.http.RouteSelector.next(RouteSelector.java:133)
at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:314)
at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:237)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:423)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:105)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:239)
at com.squareup.okhttp.internal.huc.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
at com.squareup.okhttp.internal.huc.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:25)
at retrofit.client.UrlConnectionClient.prepareRequest(UrlConnectionClient.java:68)
at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:37)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:321)
at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265)
at retrofit.RxSupport$2.run(RxSupport.java:55)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at retrofit.Platform$Android$2$1.run(Platform.java:142)
at java.lang.Thread.run(Thread.java:841)
01-08 16:19:31.606 15285-16162/asd.bdef.gh D/Retrofit﹕ ---- END ERROR
01-08 16:19:31.977 15285-15285/asd.bdef.gh D/AndroidRuntime﹕ Shutting down VM
01-08 16:19:31.977 15285-15285/asd.bdef.gh W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41c9d8b0)
01-08 16:19:31.977 15285-15285/asd.bdef.gh E/AndroidRuntime﹕ FATAL EXCEPTION: main
il dato indirizzo api non è quello reale, ma il vero uno è raggiungibile. Ho appena spento il WiFi per testare la gestione degli errori.
E un altro caso d'uso: se aggiungo all'osservabile .onExceptionResumeNext ([2 ° osservabile]) che passa al 2 ° osservabile, e non si blocca. Ma questa non è la soluzione del problema.
EDIT 2
ApiManager.login(userName, pass, new Observer<User>() {
@Override
public void onCompleted() { }
@Override
public void onError(Throwable e) {
DialogManager.showBasicErrorDialog(getApplicationContext(), e.getLocalizedMessage());
logger.showLog("Login Not ok");
e.printStackTrace();
}
@Override
public void onNext(User user) {
logger.showLog("login ok, user: " + user.getName().toString());
{...}
}
});
EDIT 3
FATAL EXCEPTION: main
rx.exceptions.OnErrorFailedException: Error occurred when trying to propagate error to Observer.onError
at rx.observers.SafeSubscriber._onError(SafeSubscriber.java:175)
at rx.observers.SafeSubscriber.onError(SafeSubscriber.java:97)
at rx.internal.operators.NotificationLite.accept(NotificationLite.java:144)
{...}
Caused by: java.lang.NullPointerException: Attempt to read from field 'rx.functions.Action0 rx.schedulers.TrampolineScheduler$TimedAction.action' on a null object reference
at rx.schedulers.TrampolineScheduler$InnerCurrentThreadScheduler.enqueue(TrampolineScheduler.java:85)
Grazie in anticipo per l'aiuto.
Potrebbe pubblicare il tuo traccia dello stack/uscita logcat? Come si presenta il codice chiamante (la definizione dell'osservatore)? –
È stato modificato .. ma in realtà non è troppo rilevante, poiché l'errore è di proposito. ... –
L'output sopra riportato è _non l'app si arresta in modo anomalo_ - è [Retrofit logging the error] (https://github.com/square/retrofit/blob/2c1c6ec370f88e21ac219d8f343f1f6d904c1c87/retrofit/src/main/java/retrofit/RestAdapter.java # L495). Hai un filtro logcat abilitato? ... –