Android – RxJava vs AsyncTask para evitar la pérdida de memoria de getActivity ()

¿Cómo utilizar RxJava (o RxAndroid, etc) en lugar de AsyncTask en Android ayuda a evitar una fuga de contexto? En AsyncTask, si lo ejecuta y el usuario deja la aplicación, el contexto de la actividad puede ser nulo y la aplicación puede bloquearse. He oído que RxJava puede ayudar a prevenir este tipo de accidente al hacer el roscado. También he oído que puede hacer mejor el manejo de errores, a continuación, el método doInBackground de AsyncTask (que maneja mal los errores). La mayor parte del tiempo apenas vuelvo null (por ejemplo) en doInBackground si algo falla, pero he leído que RxJava puede volver el error exacto y no la fuga. ¿Puede alguien dar un ejemplo?

Esta es una pequeña demostración de un bloqueo en AsyncTask si el usuario deja la aplicación mientras intenta informar los resultados a la interfaz de usuario:

@SuppressWarnings("unused") private class GetTask extends AsyncTask<Void, Void, Void> { @Override protected void onPostExecute(String result) { pd = new ProgressDialog(getActivity().getApplicationContext());//can crash right here pd.setTitle("Grabbing Track!"); pd.setMessage("Please wait..."); pd.setCancelable(false); pd.setIndeterminate(true); pd.show(); }} 

Y aquí hay una llamada de método doInBackground que no envía errores que son útiles:

 @Override protected String doInBackground(String... params) { String myIntAsString = 1/0 + ""; //this should give an error (how do we report it to the caller?? //or if we are parsing json and it fails, how do we report it to the caller cleanly. Can RxJava help? } 

2 Solutions collect form web for “Android – RxJava vs AsyncTask para evitar la pérdida de memoria de getActivity ()”

Yo uso una combinación de dos cosas. En primer lugar, RxAndroid es realmente útil: https://github.com/ReactiveX/RxAndroid

Puede usar AppObservable.bindActivity para enlazar un observable de tal manera que su salida se observe en el subproceso principal y, si la actividad está programada para ser destruida, los mensajes no se reenviarán. Sin embargo, todavía tiene que administrar el ciclo de vida de pausa / reanudar. Para eso, utilizo una suscripción compuesta como esta (pseudojava subiendo):

 public class MyActivity extends Activity { private final CompositeSubscription subscriptions = new CompositeSubscription(); @Override public void onResume() { super.onResume(); subscriptions.add(AppObservable.bindActivity(this, myObservable) .subscribe()); subscriptions.add(AppObservable.bindActivity(this, myOtherObservable) .subscribe()); } @Override public void onPause() { subscriptions.clear(); super.onPause(); } } 

Obviamente, usted desea hacer más en subscribe si desea hacer algo con los datos, pero lo importante es recopilar las instancias de Subscription devueltas y agregarlas a CompositeSubscription . Cuando los borra, los cancelará también.

El uso de estos "dos trucos extraños" debe evitar que las cosas vuelvan a la Actividad cuando es un estado inoperante.

Creo que lo bueno de RxJava es si tienes un montón de tareas que puedes poner en una secuencia tal que sabes cuando uno termina y el próximo está a punto de comenzar. en un AsyncTask si tiene más de una ejecución, no tiene ninguna garantía de que la tarea se completa primero y luego tienes que hacer un montón de errores de verificación si te importa orden. Así RxJava le permite secuenciar las llamadas.

En cuanto a las fugas de memoria podemos tener un AsyncTask como una clase interna de una actividad. Ahora, desde su vinculado a la actividad cuando la actividad se destruye que el contexto sigue siendo alrededor y no será recolectado basura, esa es la parte de pérdida de memoria.

Aquí es donde RxJava puede ayudar. si se producen errores, podemos llamar al método onError de los suscriptores. El subcriptor puede tener este aspecto:

  public Observable<JsonObject> get_A_NetworkCall() { // Do your network call...but return an observable when done } Subscription subscription = get_A_NetworkCall() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<jsonResponse>() { @Override public void onCompleted() { // Update UI } @Override public void onError() { // show error on UI } @Override public void onNext(JsonObject response) { // Handle result of jsonResponse } }); 

o algo similar – esto es psuedocode. El punto es que puede reportar los errores de manera más limpia y cambiar los hilos en una sola línea. Aquí estamos reportando sobre el hilo principal de androides pero haciendo el trabajo en un nuevo hilo. Después de que terminemos en nuestro método de actividades onDestroy podemos simplemente cancelar la suscripción a lo observable y lo mata y evita cualquier pérdida de memoria que encontremos con AsyncTask. Esto para mí debe ser el reemplazo de cualquier asyncTasks.

  • Android: Realm.getInstance (context) devuelve una instancia de dominio ya cerrada
  • RxJava con presentador y fragmento retenido para cambios de configuración
  • Prueba Espresso con RxLoader
  • AsyncTask en RxJava
  • Problema relacionado con API observable y cancelación de suscripción
  • RxJava Break Chain en Condicional
  • Cómo recibir la última emisión de secuencia al llamar a rx.Observable.sample ()?
  • Android RxJava, sin bloqueo?
  • RxJava + Retrofit -> BaseObservable para llamadas API para manejo centralizado de respuesta
  • Cancelación de varias suscripciones a la vez en RxAndroid - Android
  • Sustitución de EventBus por RxJava - N suscriptores siempre escuchando
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.