[Corutina de Kotlin] Transformación de corrutina basada en el proyecto RxJava

Inserte la descripción de la imagen aquíRecientemente, Android anunció su completa obsolescencia AsyncTasky la recomendó Coroutinecomo la solución de programación asincrónica preferida.

Si no hay suspenso de que AsyncTask sea reemplazado por Coroutine, RxJava¿cómo eliges entre Coroutine?

Dios J dio su opinión muy temprano. El flujo aún estaba por llegar, ahora me temo que Dios Observable, Subjecttambién hace mucho que no. Los días en que RxJava fue abandonado en Android pueden no estar muy lejos.

Entonces, ¿cómo se puede transformar simplemente un proyecto MVVM de RxJava existente en Coroutine?

Ejemplo de RxJava


Tome un proyecto de RxJava como ejemplo, la capa Modelo realiza solicitudes de datos basadas en Single

class Api {
    
    
  fun fetchPersons(): Single<List<Person>> = ...
}
class ViewModel(
    private val api: Api = Api(),
    private val scheduler: Scheduler = Schedulers.io()
) {
    
    
  private val mutablePersons = MutableLiveData<List<Person>>()
  val persons: LiveData<List<Person>> = mutablePersons

  fun onCreate() {
    
    
    api.fetchPersons()
        .subscribeOn(scheduler)
        .subscribe(mutablePersons::postValue)
  }
}

kotlinx-coroutines-rx2


kotlinx-coroutines-rx2 es algo bueno que puede ayudarnos a cambiar entre Rx2 y Coroutine.

Además de Rx2, otras bibliotecas reactivas como Rx3 también admiten https://github.com/Kotlin/kotlinx.coroutines/tree/master/reactive

Coroutine => Rx2

Inserte la descripción de la imagen aquí

Rx2 => Corutina

Inserte la descripción de la imagen aquí
Use SingleSource.await, puede convertir la capa Single of the Model en el ejemplo anterior en una función de suspensión

class ViewModel(
    private val api: Api = Api(),
    private val coroutineContext: CoroutineContext = CommonPool
) {
    
    
  private val mutablePersons = MutableLiveData<List<Person>>()
  val persons: LiveData<List<Person>> = mutablePersons

  fun onCreate() {
    
    
    launch(coroutineContext) {
    
    
      //将Rx请求转换挂起函数
      val persons = api.fetchPersons().await()
      mutablePersons.postValue(persons)
    }
  }
}

Más notas


Aunque es casi fácil convertir Rx a Coroutine en el ejemplo, si desea usarlo en un proyecto real, es posible que deba procesarlo un poco:

class PersonsViewModel(
    private val api: Api = Api(),
    coroutineContext: CoroutineContext = CommonPool
) : ViewModel() {
    
    
  private val compositeJob = Job() //1
  private val mutablePersons = MutableLiveData<List<Person>>()
  val persons: LiveData<List<Person>> = mutablePersons

  init {
    
    
    launch(coroutineContext, parent = compositeJob) {
    
    
      try {
    
     //2
        val persons = api.fetchPersons().await()
        mutablePersons.postValue(persons)
      } catch (e: Exception) {
    
    
        ...
      }
    }
  }

  override fun onCleared() {
    
    
    compositeJob.cancel() 
  }
  1. El trabajo principal especificado al iniciar la corrutina onClearedestá unificado en ese momento para cancelevitar fugas. Por supuesto, este trabajo ahora se puede hacer a través de ViewModella extensión KTX
  2. En launchpor try...catch...la captura de la alternativa anormal Rx onError, más detalles sobre la anomalía puede referirse a corrutina capturados Kotlin corrutina Buenas Prácticas

Comparte programadores con RxJava


Use Scheduler.asCoroutineDispatcher para convertir RxJava Schedulerspara Dispatcherque el grupo de subprocesos antes y después de la reconstrucción no cambie para garantizar la coherencia.

object AppCoroutineDispatchers(
    val io: CoroutineContext = Schedulers.io().asCoroutineDispatcher(),
    val computation: CoroutineContext = Schedulers.computation().asCoroutineDispatcher(),
    val ui: CoroutineContext = UI
)

//use
launch(AppCoroutineDispatchers.io) {
    
     ... }

Último vistazo a una ola de operaciones inversas


Aunque Coroutine se recomienda más para Android, kotlinx-coroutines-rx2 aún proporciona una API amigable para convertir Coroutine a Rx2, así que echemos un vistazo a cómo realizar la operación inversa:

Utilice rxSinglela función de suspensión paraSingle

class Api {
    
    
  suspend fun fetchPersons(): List<Person> = ...
}
class ViewModel(
    private val api: Api = Api(),
    private val scheduler: Scheduler = Schedulers.io(),
    val coroutineContext: CoroutineContext = CommonPool
) {
    
    
  private val mutablePersons = MutableLiveData<List<Person>>()
  val persons: LiveData<List<Person>> = mutablePersons

  fun onCreate() {
    
    
    rxSingle(coroutineContext) {
    
     api.fetchPersons() }
        .subscribeOn(scheduler)
        .subscribe(mutablePersons::postValue)
  }
}

Supongo que te gusta

Origin blog.csdn.net/vitaviva/article/details/107435285
Recomendado
Clasificación