RxJava y Retrofit2: NetworkOnMainThreadException
Me doy cuenta de que estoy usando subscribeOn () / observerOn () en el MainThread. ¿Cuál es el conjunto de opciones que puedo pasar a subscribeOn ()? ¿Cuál es el conjunto de opciones que puedo pasar a observerOn ()?
12-17 21:36:09.154 20550-20550/rx.test D/MainActivity2: [onCreate] 12-17 21:36:09.231 20550-20550/rx.test D/MainActivity2: starting up observable... 12-17 21:36:09.256 20550-20550/rx.test D/MainActivity2: [onError] 12-17 21:36:09.256 20550-20550/rx.test W/System.err: android.os.NetworkOnMainThreadException
GovService.java
- Cómo utilizar CompositeDisposable de RxJava 2?
- Android gestiona la solicitud múltiple rxJava en el dispositivo de rotación
- Rx 2 Android ¿qué es mejor Single o Observable para llamadas api?
- Maneje la respuesta vacía con retrofit y rxjava 2.x
- Encadenamiento de servicios de Retrofit con soporte de RxJava
import java.util.List; import retrofit.Call; import retrofit.http.GET; import rx.Observable; public interface GovService { @GET("/txt2lrn/sat/index_1.json") Observable<MyTest> getOneTestRx(); }
MyTest.java
public class MyTest { private String name, url; private int num; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } @Override public String toString() { return "Name: " + this.name + ", num: " + this.num + ", url: " + this.url; } }
MainActivity2.java
import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.util.Log; import retrofit.GsonConverterFactory; import retrofit.Retrofit; import retrofit.RxJavaCallAdapterFactory; import rx.Observable; import rx.Subscriber; import rx.android.schedulers.AndroidSchedulers; import rx.schedulers.Schedulers; public class MainActivity2 extends AppCompatActivity { private final String TAG = getClass().getSimpleName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "[onCreate]"); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); RecyclerView mRV = (RecyclerView) findViewById(R.id.rv); mRV.setLayoutManager(new LinearLayoutManager(this));// setup LayoutManager mRV.setItemAnimator(new DefaultItemAnimator());// setup ItemAnimator // setup retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://goanuj.freeshell.org") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .build(); GovService service = retrofit.create(GovService.class); Log.d(TAG, "starting up observable..."); Observable<MyTest> o = service.getOneTestRx(); o.subscribeOn(Schedulers.io()); o.observeOn(AndroidSchedulers.mainThread()); o.subscribe(new Subscriber<MyTest>() { @Override public void onCompleted() { Log.d(TAG, "[onCompleted] "); } @Override public void onError(Throwable t) { Log.d(TAG, "[onError] "); t.printStackTrace(); } @Override public void onNext(MyTest m) { Log.d(TAG, "[onNext] " + m.toString()); } }); } }
- Rx java retrofit 2 manejo de errores
- RxJava: ¿Cómo puedo hacer una observación de búsqueda-una vez-y-reutilización?
- Comprobación de Internet, dónde colocar al usar MVP, RX y Retrofit
- ¿Es necesario darse de baja?
- Encadenamiento de RxJava observables con callbacks / listeners
- AndroidRX - ejecuta el método en segundo plano
- Desbordamiento de pila al utilizar Retrofit rxjava concatWith
- ¿Cómo se muestra spinner si RxJava observable toma mucho tiempo?
Vuelva a escribir la última parte de su código en:
service.getOneTestRx() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<MyTest>() { @Override public void onCompleted() { Log.d(TAG, "[onCompleted] "); } @Override public void onError(Throwable t) { Log.d(TAG, "[onError] "); t.printStackTrace(); } @Override public void onNext(MyTest m) { Log.d(TAG, "[onNext] " + m.toString()); } });
Nota importante de @akarnokd:
Vale la pena mencionar que uno necesita encadenar las llamadas como aquí porque Observable no es el patrón del constructor (donde se modifican los ajustes de un objeto existente)
Debería llamar a Observable.unsubscribeOn(Schedulers.io())
, retrofit
cancelará la suscripción al final de una solicitud http.
En RxJavaCallAdapterFactory
de retrofit-rxjava-adapter
Acciones como esta.
if (!subscriber.isUnsubscribed()) { subscriber.onCompleted(); }
Pero cuando el subscriber
es un SafeSubscriber
, llamará unsubscribe
finalmente.
Tengo este problema en mi aplicación.
Código completo:
o.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .unsubscribeOn(Schedulers.io());