RxJava 2 para Apps Android: RxBinding y RxLifecycle
() translation by (you can also view the original English article)
RxJava es una de las librerías más populares para traer programación reactive a la plataforma Android, y es esta serie de tres partes te estaré mostrando cómo comenzar a usar esta librería en tus propios proyectos Android.
En Comienza Con RxJava 2 para Android, vimos lo que es RxJava y es que ofrece a desarrolladores Android, antes de crear una aplicación Hola Mundo que demostraba los tres componentes nucleares de RxJava: un Observable, un Observer, y una suscripción.
En el tutorial Operadores de Programación Reactive en RxJava, vimos cómo hacer transformaciones complejas de datos usando operadores, y cómo puedes combinar Operator
s y Scheduler
s para finalmente hacer multi-hilos en Android una experiencia indolora.
También tocamos RxAndroid, una librería específicamente diseñada para ayudarte a usar RxJava en tus proyectos Android, pero hay mucho más que explorar en RxAndroid. Así qué, en este artículo, voy a enfocarme únicamente en la familia de librerías RxAndroid.
Muy parecido a RxJava, RxAndroid sufrió una revisión masiva en su liberación de versión 2. El equipo de RxAndroid decidió modularizar la librería, moviendo mucha de su funcionalidad a módulos complementarios dedicados RxAndroid.
En este artículo, vamos a mostrarte cómo configurar y usar algunos de los módulos RxAndroid más populares y poderosos---incluyendo una librería que puede hacer listeners, handlers y TextWatchers
cosa del pasado dándote la habilidad de manejar cualquier evento UI Android como un Observable
.
Y ya que las fugas de memoria ocasionadas por suscripciones incompletas son la desventaja más grande de usar RxJava en tus aplicaciones Android, también te mostraré cómo usar un módulo RxAndroid que pueda manejar el proceso de suscripción por ti. Al final de este artículo, sabrás como usar RxJava en cualquier Activity
o Fragment
sin correr el riesgo de encontrar cualquier fuga de memoria relacionada con Rx-Java.
Creando Más UIs Android Reactive
Reaccionar a eventos UI tales como toques, deslizamientos o entradas de texto es una parte fundamental de desarrollar prácticamente cualquier aplicación Android, ero manejar eventos Android UI no es particularmente sencillo.
Típicamente reaccionas a eventos usando una combinación de listeners, handlers, TextWatchers
, y posiblemente otros componentes dependiendo del tipo de UI que estás creando. Cada uno de estos componentes requiere que escribas una cantidad significativa de código base, y para empeorar las cosas no hay consistencia en cómo implementas estos diferentes componentes. Por ejemplo, puedes manejar eventos OnClick
implementando un OnClockListener
:
1 |
Button button = (Button)findViewById(R.id.button); |
2 |
button.setOnClickListener(new View.OnClickListener() { |
3 |
@Override
|
4 |
public void onClick(View v) { |
5 |
//Perform some work//
|
6 |
}
|
7 |
});
|
Pero esto es completamente diferente de cómo implementarías un TextWatcher:
1 |
final EditText name = (EditText) v.findViewById(R.id.name); |
2 |
//Create a TextWatcher and specify that this TextWatcher should be called whenever the EditText’s content changes//
|
3 |
name.addTextChangedListener(new TextWatcher() { |
4 |
@Override
|
5 |
public void beforeTextChanged(CharSequence s, int start, int count, int after) { |
6 |
}
|
7 |
|
8 |
@Override
|
9 |
public void onTextChanged(CharSequence s, int start, int before, int count) { |
10 |
//Perform some work//
|
11 |
}
|
12 |
|
13 |
@Override
|
14 |
public void afterTextChanged(Editable s) { |
15 |
}
|
16 |
});
|
Esta falta de consistencia puede agregar potencialmente mucha complejidad a tu código. Y si tienes componentes UI que dependan de la salida de otros componentes UI, ¡entonces prepárate para que las cosas se compliquen aún más! Incluso un simple caso de uso---como pedir al usuario que teclee su nombre en un EditText
para que puedas personalizar el texto que aparece en TextViews
subsecuentes---requiere de callbacks anidados, los cuáles son notoriamente difíciles de implementar y mantener. (Alguna gente se refiere a los callbacks anidados como "infierno callback.")
Claramente, una aproximación estandarizada para manejar eventos UI tiene el potencial para simplificar tu código enormemente, y RxBinding es una librería que hace justo eso, proporcionando enlaces que te permiten convertir cualquier evento View
Android en un Observable
.
Una vez que has convertido un evento de vista en un Observable
, este emitirá sus eventos UI como flujos de información a los que puedes suscribirte exactamente de la misma forma en la que te suscribirías a cualquier otro Observable
.
Ya que ya hemos visto cómo capturar un evento de clic usando el OnClickListener
estándar de Android, veamos cómo lograrías los mismos resultados usando RxBinding.
1 |
import com.jakewharton.rxbinding.view.RxView; |
2 |
|
3 |
...
|
4 |
|
5 |
Button button = (Button) findViewById(R.id.button); |
6 |
RxView.clicks(button) |
7 |
.subscribe(aVoid -> { |
8 |
//Perform some work here//
|
9 |
});
|
No solo esta aproximación es más concisa, sino que es una implementación estándar que puedes aplicar a todos los eventos UI que ocurren a lo largo de tu app. Por ejemplo, capturar entradas de texto sigue el mismo patrón que capturar eventos de clic:
1 |
RxTextView.textChanges(editText) |
2 |
.subscribe(charSequence -> { |
3 |
//Perform some work here//
|
4 |
});
|
Una App de Ejemplo Con RxBinding
Así que puedes ver exactamente como RxBinding puede simplificar el código relacionado a UI de tu app, creemos una app que demuestre unos cuantos de estos enlaces en acción. También voy a incluir un View
que depende de la salida de otro View
, para demostrar como RxBinding simplifica crear relaciones entre componentes UI.
Esta app va a consistir en:
- Un
Button
que muestre unToast
cuando se presione. - Un
EditText
que detecta cambios de texto. - Un
TextView
que se actualiza para mostrar los contenidos delEditText
.
Configuración de Proyecto
Crea un proyecto de Android Studio con los ajustes de tu elección, y después abre tu archivo build.gradle a nivel de módulo y agrega la última versión de la librería RxBinding como una dependencia de proyecto. En los intereses de mantener el código base al mínimo, también voy a usar lambdas, así que actualicé mi archivo build.gradle para soportar esta característica de Java 8:
1 |
apply plugin: 'com.android.application' |
2 |
android { |
3 |
compileSdkVersion 25 |
4 |
buildToolsVersion "25.0.2" |
5 |
defaultConfig { |
6 |
applicationId "com.jessicathornsby.myapplication" |
7 |
minSdkVersion 23 |
8 |
targetSdkVersion 25 |
9 |
versionCode 1 |
10 |
versionName "1.0" |
11 |
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" |
12 |
|
13 |
//Enable the Jack toolchain// |
14 |
|
15 |
jackOptions { |
16 |
enabled true |
17 |
} |
18 |
} |
19 |
|
20 |
buildTypes { |
21 |
release { |
22 |
minifyEnabled false |
23 |
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
24 |
} |
25 |
} |
26 |
|
27 |
//Set sourceCompatibility and targetCompatibility to JavaVersion.VERSION_1_8// |
28 |
|
29 |
compileOptions { |
30 |
sourceCompatibility JavaVersion.VERSION_1_8 |
31 |
targetCompatibility JavaVersion.VERSION_1_8 |
32 |
} |
33 |
} |
34 |
|
35 |
dependencies { |
36 |
compile fileTree(dir: 'libs', include: ['*.jar']) |
37 |
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { |
38 |
exclude group: 'com.android.support', module: 'support-annotations' |
39 |
}) |
40 |
|
41 |
//Add the core RxBinding library// |
42 |
|
43 |
compile 'com.jakewharton.rxbinding:rxbinding:0.4.0' |
44 |
compile 'com.android.support:appcompat-v7:25.3.0' |
45 |
|
46 |
//Don’t forget to add the RxJava and RxAndroid dependencies// |
47 |
|
48 |
compile 'io.reactivex.rxjava2:rxandroid:2.0.1' |
49 |
compile 'io.reactivex.rxjava2:rxjava:2.0.5' |
50 |
testCompile 'junit:junit:4.12' |
51 |
} |
52 |
} |
Si estás trabajando con múltiples librerías RxJava, es posible que encuentres un mensaje de error Duplicate files copied in APK META-INF/DEPENDENCIES en tiempo de compilación. Si encuentras este error, entonces la solución es suprimir estos archivos duplicados agregando lo siguiente a tu archivo build.gradle a nivel de módulo:
1 |
android { |
2 |
packagingOptions { |
3 |
|
4 |
//Use “exclude” to point at the specific file (or files) that Android Studio is complaining about// |
5 |
|
6 |
exclude 'META-INF/rxjava.properties' |
7 |
} |
Crea el Layout de Main Activity
Sincroniza tus archivos Gradle, y después crea un layout consistente de un Button
, un EditText
, y un TextView
:
1 |
<?xml version="1.0" encoding="utf-8"?>
|
2 |
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android" |
3 |
xmlns:tools="http://schemas.android.com/tools" |
4 |
android:layout_width="match_parent" |
5 |
android:layout_height="match_parent" |
6 |
android:orientation="vertical" |
7 |
tools:context=".MainActivity" > |
8 |
|
9 |
<Button
|
10 |
android:text="Button" |
11 |
android:layout_width="wrap_content" |
12 |
android:layout_height="wrap_content" |
13 |
android:id="@+id/button" /> |
14 |
|
15 |
<EditText
|
16 |
android:layout_width="wrap_content" |
17 |
android:layout_height="wrap_content" |
18 |
android:inputType="textPersonName" |
19 |
android:text="Type here" |
20 |
android:ems="10" |
21 |
android:id="@+id/editText" /> |
22 |
|
23 |
<TextView
|
24 |
android:text="TextView" |
25 |
android:layout_width="match_parent" |
26 |
android:layout_height="wrap_content" |
27 |
android:id="@+id/textView" /> |
28 |
|
29 |
</LinearLayout>
|
Codifica los Enlaces de Evento
Ahora veamos cómo usarías estos RxBinding para capturar los diferentes eventos UI a los que nuestra aplicación necesita reaccionar. Para comenzar, declara tus imports y define la clase MainActivity
.
1 |
package com.jessicathornsby.myapplication; |
2 |
|
3 |
import android.os.Bundle; |
4 |
import android.support.v7.app.AppCompatActivity; |
5 |
import android.widget.Button; |
6 |
import android.widget.EditText; |
7 |
import android.widget.TextView; |
8 |
import android.widget.Toast; |
9 |
|
10 |
//Import the view.RxView class, so you can use RxView.clicks//
|
11 |
|
12 |
import com.jakewharton.rxbinding.view.RxView; |
13 |
|
14 |
//Import widget.RxTextView so you can use RxTextView.textChanges//
|
15 |
|
16 |
import com.jakewharton.rxbinding.widget.RxTextView; |
17 |
|
18 |
public class MainActivity extends AppCompatActivity { |
19 |
@Override
|
20 |
protected void onCreate(Bundle savedInstanceState) { |
21 |
super.onCreate(savedInstanceState); |
22 |
setContentView(R.layout.activity_main); |
23 |
|
24 |
Button button = (Button) findViewById(R.id.button); |
25 |
TextView textView = (TextView) findViewById(R.id.textView); |
26 |
EditText editText = (EditText) findViewById(R.id.editText); |
27 |
|
28 |
//Code for the bindings goes here//
|
29 |
//...//
|
30 |
}
|
31 |
}
|
Ahora puedes comenzar a agregar enlaces para responder a eventos UI. El método RxView.clicks
es usado para enlazar eventos clic. Crea un enlace para mostrar un toast siempre que el botón sea presionado.
1 |
RxView.clicks(button) |
2 |
.subscribe(aVoid -> { |
3 |
Toast.makeText(MainActivity.this, "RxView.clicks", Toast.LENGTH_SHORT).show(); |
4 |
}); |
Después, usa el método RxTextView.textChanges()
para reaccionar al evento de cambio de texto actualizando el TextView
con los contenidos de nuestro EditText
.
1 |
RxTextView.textChanges(editText) |
2 |
.subscribe(charSequence -> { |
3 |
textView.setText(charSequence); |
4 |
}); |
Cuando ejecutes tu app, terminarás con una pantalla como la siguiente.



Instala tu proyecto en un smartphone Android físico o tablet o un AVD compatible, y después pasa algún tiempo interactuando con los distintos elementos UI. Tu app debería reaccionar a eventos clic y entrada de texto de manera normal---¡y todo sin un listener, TextWatcher o callback a la vista!
RxBinding para Vistas de Librería de Soporte
Mientras que la librería nuclear RxBinding proporciona enlaces para todos los elementos UI que conforman la plataforma estándar Android, también hay módulos RxBinding hermanos que proporcionan enlaces para las Vistas que están incluídas como parte de las distintas librerías de soporte de Android.
Si has agregado una o más librerías de soporte a tu proyecto, entonces típicamente querrás agregar el módulo RxBinding correspondiente también.
Estos módulos hermanos siguen convención de nomenclatura que hace sencillo identificar la librería de soporte de Android correspondiente: cada módulo hermano simplemente toma el nombre de la librería de soporte, y reemplaza com.android
con com.jakewharton.rxbinding2:rxbinding
.
compile com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-leanback-v17:2.0.0'
Si estás usando Kotlin en tus proyectos Android, entonces también hay una versión Kotlin disponible para cada módulo RxBinding. Para acceder a la versión Kotlin, simplemente adjunta -kotlin
al nombre de la librería con la que quieres trabajar, así:
1 |
compile 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0' |
Se vuelve:
1 |
compile 'com.jakewharton.rxbinding2:rxbinding-design-kotlin:2.0.0' |
Una vez que has convertido un evento View
a un Observable
, todos esos eventos son emitidos como un flujo de datos. Como hemos visto, puedes suscribir a estos flujos y después realizar cualquier tarea que necesites para este evento UI particular a disparar, tal como mostrar un Toast
o actualizar un TextView
. Sin embargo, también puedes aplicar cualquiera de los operadores de la enorme colección de RxJava a este flujo observable, e incluso encadenar múltiples operadores para realizar transformaciones complejas en tus eventos UI.
Hay demasiados operadores para discutir en un solo artículo (y la documentación oficial lista todos los operadores de cualquier modo) pero cuando se trata de trabajar con eventos UI Android, hay algunos cuantos operadores que pueden resultar particularmente útiles.
El Operador debounce()
Primeramente, si estás preocupado de que un usuario impaciente presione repetidamente un elemento UI, potencialmente confundiendo a tu app, entonces puedes usar el operador debounce()
para filtrar cualquier evento UI que sea emitido en rápida sucesión.
En el siguiente ejemplo, estoy especificando que este botón debería reacción a un evento OnClick
solo si ha habido al menos una brecha de 500 milisegundos desde el evento clic anterior:
1 |
RxView.clicks(button) |
2 |
.debounce(500, TimeUnit.MILLISECONDS) |
3 |
.subscribe(aVoid -> { |
4 |
Toast.makeText(MainActivity.this, "RxView.clicks", Toast.LENGTH_SHORT).show(); |
5 |
});
|
El Operador publish()
También puedes usar el operador publish()
para adjuntar múltiples listeners a la misma vista, algo que ha sido tradicionalmente difícil de implementar en Android.
El operador publish()
convierte un Observable
estándar en un observable connectable. Mientras que un observable regular comienza a emitir elementos tan pronto como el primer observador se suscribe a el, un observable connectable no emitirá nada hasta que se lo instruyas explícitamente, aplicando el operador connect()
. Esto te da una ventana de oportunidad en la cuál puedes suscribir varios observadores, sin que el observable comience a emitir elementos tan pronto la primer suscripción suceda.
Una vez que has creado todas tus suscripciones, simplemente aplica el operador connect()
y el observable comenzará a emitir datos a todos sus observadores asignados.
Evita Fugas de Memoria que Colapsen la App
Como vimos a lo largo de la serie, RxJava puede ser una poderosa herramienta para crear aplicaciones Android más reactivas e interactivas, con mucho menos código del que típicamente necesitarías para obtener los mismos resultados usando solo Java. Sin embargo, hay una gran desventaja en usar RxJava en tus aplicaciones Android---el potencial para las fugas de memoria causado por suscripciones incompletas.
Estas fugas de memoria ocurren cuando el sistema Android intenta destruir una Activity
que contiene un Observable
en ejecución. Ya que el observable se está ejecutando, su observador aún estará reteniendo una referencia a la actividad, y el sistema no será capaz de recolectar basura en esta actividad como resultado.
Ya que Android destruye y re-crea Activity
s cada vez que la configuración del dispositivo cambia, tu app podría estar creando una Activity
duplicada cada vez que el usuario cambia entre modo retrato y panorámico, así como cada vez que abren y cierran el teclado de su dispositivo.
Estas actividades estarán en segundo plano, potencialmente sin recolectar nunca basura. Ya que las Activities son objetos grandes, esto puede llevar rápidamente a problemas serios de administración de memoria, especialmente ya que los teléfonos Android y tablets tienen memoria limitada para empezar. La combinación de una fuga grande de memoria y memoria limitada puede resultar rápidamente en un error Out Of Memory.
Las fugas de memoria RxJava pueden tener el potencial para causar estragos en el desempeño de tu aplicación, pero hay una librería RxAndroid que te permite usar RxJava en tu app sin tener que preocuparte sobre fugas de memoria.
La librería RxLifeCycle, desarrollada por Trello, proporciona APIs de manejo de ciclo de vida que puedes usar para limitar la vida de un Observable
al ciclo de vida de un Activity
o Fragment
. Una vez que esta conexión está hecha, RxLifecycle terminará la secuencia del observable en respuesta a los eventos del ciclo de vida que ocurran en el activity o fragment asignado a ese observable. Esto significa que puedes crear un observable que termine automáticamente siempre que un activity o fragment es destruido.
Nota que estamos hablando de terminar una secuencia, y no cancelar suscripción. Aunque frecuentemente se habla sobre RxLifecycle en el contexto de administrar el proceso de suscripción/cancelar suscripción, técnicamente no cancela la suscripción de un observador. En su lugar, la librería RxLifecycle termina la secuencia observable emitiendo ya sea el método onComplete()
o onError()
. Cuando cancelas la suscripción, el observador deja de recibir notificaciones de su observable, incluso si ese observable aún está emitiendo elementos. Si requieres específicamente comportamiento de cancelación de suscripción, entonces eso es algo que necesitarás implementar tu mismo.
Usando RxLifecycle
Para usar RxLifeCycle en tus proyectos Android, abre tu archivo build.gradle a nivel módulo y agrega la última versión de la librería RxLifecycle, más la librería Android RxLifecycle:
1 |
dependencies { |
2 |
... |
3 |
... |
4 |
compile 'com.trello.rxlifecycle2:rxlifecycle:2.0.1' |
5 |
compile 'com.trello.rxlifecycle2:rxlifecycle-android:2.0.1' |
Después, en la Activity
o Fragment
en donde quieres usar las APIs de manejo de la librería lifecycle, extiende ya sea RxActivity
, RxAppCompatActivity
o RxFragment
, y agrega la declaración de importación correspondiente, por ejemplo:
1 |
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity; |
2 |
|
3 |
...
|
4 |
|
5 |
public class MainActivity extends RxAppCompatActivity { |
Cuando se trata de enlazar un Observable
al ciclo de vida de un Activity
o Fragment
, puedes especificar el evento lifecycle en donde el observable debería terminar, o puedes dejar que la librería RxLifecycle decida cuándo debería terminar la secuencia observable.
Por defecto, RxLifecycle terminará un observable en el evento de ciclo de vida complementario en donde ocurrió la suscripción, a´si que si suscribes a un observable durante el método onCreate()
de tu Activity, entonces RxLifecycle terminará la secuencia observable durante el método onDestroy()
de esa Activity. Si suscribes durante el método onAttach()
de un Fragment
, entonces RxLifecycle terminará la secuencia en el método onDetach()
.
Puedes dejar esta decisión a RxLifecycle, usando RxLifecycleAndroid.bindActivity
:
1 |
Observable<Integer> myObservable = Observable.range(0, 25); |
2 |
|
3 |
...
|
4 |
|
5 |
@Override
|
6 |
public void onResume() { |
7 |
super.onResume(); |
8 |
myObservable
|
9 |
.compose(RxLifecycleAndroid.bindActivity(lifecycle)) |
10 |
.subscribe(); |
11 |
}
|
De manera alternativa, puedes especificar el evento de ciclo de vida en donde RxLifecycle debería terminar una secuencia Observable
, usando RxLifecycle.bindUntilEvent
.
Aquí, estoy especificando que la secuencia observable debería ser terminada en onDestroy()
:
1 |
@Override
|
2 |
public void onResume() { |
3 |
super.onResume(); |
4 |
myObservable
|
5 |
.compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) |
6 |
.subscribe(); |
7 |
}
|
Trabajando con Permisos Android Marshmallow
La librería final que vamos a ver es RxPermissions, que fue diseñada para ayudarte a usar RxJava con el nuevo modelo de permisos introducidos en Android 6.0. Esta librería también te permite hacer una petición de permiso y manejar el resultado del permiso en la misma ubicación, en lugar de solicitar el permiso en un lugar y después manejar sus resultados de manera separada, en Activity.onRequestPermissionsResult()
.
Comienza agregando la librería RxPermissions a tu archivo build.gradle:
1 |
compile 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.3@aar' |
Después, crea una instancia de RxPermissions:
1 |
RxPermissions rxPermissions = new RxPermissions(this); |
Después estás listo para comenzar a hacer peticiones de permisos vía la librería RxPermissions, usando la siguiente fórmula:
1 |
rxPermissions.request(Manifest.permission.READ_CONTACTS) |
2 |
.subscribe(granted -> { |
3 |
if (granted) { |
4 |
// The permission has been granted//
|
5 |
} else { |
6 |
// The permission has been denied//
|
7 |
}
|
8 |
});
|
En dónde asignas tus peticiones de permisos es crucial, ya que siempre hay una posibilidad de que la Activity
anfitrión sea destruída y después recreada mientras que el diálogo de permisos está en pantalla, usualmente debido a un cambio de configuración tal como el usuario moviéndose entre modos horizontal y vertical. Si esto ocurre, entonces su suscripción podría no ser recreada, lo que significa que no serás suscrito al observable de RxPermissions y no recibirás la respuesta del usuario al diálogo de petición de permiso. Para garantizar que tu aplicación reciba la respuesta del usuario, siempre invoca tu petición durante una fase de inicialización tal como Activity.onCreate()
, Activity.onResume()
, or View.onFinishInflate()
.
No es poco común que las características requieran varios permisos. Por ejemplo, enviar un mensaje SMS usualmente requiere que tu app tenga los permisos SEND_SMS
and READ_CONTACTS
. La librería RxPermissions proporciona un método conciso de hacer múltiples peticiones de permisos, y después combinar las respuestas de los usuarios en una sola respuesta false
(uno o más permisos fueron denegados) o true
(todos los permisos fueron concedidos) a la que puedes reaccionar después de manera acorde.
1 |
RxPermissions.getInstance(this) |
2 |
.request(Manifest.permission.SEND_SMS, |
3 |
Manifest.permission.READ_CONTACTS) |
4 |
.subscribe(granted -> { |
5 |
if (granted) { |
6 |
// All permissions were granted//
|
7 |
} else { |
8 |
//One or more permissions was denied//
|
9 |
}
|
10 |
});
|
Típicamente querrás disparar una petición de permiso en respuesta a un evento UI, tal como el usuario presionando un elemento de menú o botón, así que RxPermissions y RxBinding son dos librerías que funcionan particularmente bien juntas.
Manejar el evento UI como un observable y hacer la petición de permiso vía RxPermissions te permite hacer mucho trabajo con solo unas cuántas líneas de código:
1 |
RxView.clicks(findViewById(R.id.enableBluetooth)) |
2 |
.compose(RxPermissions.getInstance(this).ensure(Manifest.permission.BLUETOOTH_ADMIN)) |
3 |
.subscribe(granted -> { |
4 |
// The ‘enableBluetooth’ button has been clicked//
|
5 |
});
|
Conclusión
Después de leer este artículo, tienes algunas ideas sobre como cortar mucho código base de tus aplicaciones Android---usando RxJava para manejar todos los eventos UI de tu aplicación, y haciendo tus peticiones de permisos vía RxPermissions. También vimos cómo puedes usar RxJava en cualquier Activity
o Fragment
de Android, sin tener que preocuparte por las fugas de memoria que podrían ser causadas por suscripciones incompletas.
Hemos explorado algunas de las librerías RxJava y RxAndroid más importantes en esta serie, pero si tienes curiosidad de ver qué más tiene que ofrecer RxJava a desarrolladores Android, revisa algunas de las muchas otras librerías RxAndroid. Encontrarás una lista exhaustiva de librerías RxAndroid adicionales en GitHub.
Mientras tanto, ¡revisa algunas de nuestras otras publicaciones de desarrollo Androis aquí en Envato Tuts+!