Solo estoy leyendo y aprendiendo sobre rutinas en Kotlin para usar en una pequeña biblioteca con fines de diversión/aprendizaje. En la documentación, puedes hacer algo como
GlobalScope.launch { }Así que en mi método,
fun myMethod() { GlobalScope.launch { // do some networking code } } ¿Es una buena práctica usar GlobalScope para lanzar una rutina para una biblioteca? En los documentos dice
El código de la aplicación generalmente debe usar CoroutineScope definido por la aplicación; se desaconseja enfáticamente usar async o iniciar en la instancia de GlobalScope.
Esto es obviamente una biblioteca y no necesariamente un código de aplicación. Pero no estaba seguro de si esa era la mejor manera de hacer networking en segundo plano con rutinas.
yo también probé
runBlocking { async { // do some networking code } } Pensando que runBlocking introduce un nuevo ámbito de rutina, pero creo que en este caso hereda el ámbito de sus padres, que es el hilo principal, así que obtengo una excepción sobre la ausencia de redes en el hilo principal de la interfaz de usuario.
Puede crear una función de suspensión, y esto obligará a que el usuario llame a esto desde una rutina. Si su método usa withContext , no tiene que preocuparse por GlobalScope o configurar el alcance. withContext simplemente le dice a la corrutina qué contexto usar (para redes, querrá IO . Y el alcance ahora está determinado por cómo lo inicie el usuario.
La forma en que construiría su método sería:
suspend fun myMethod() = withContext(Dispatchers.IO) { // do some networking code }Dependiendo de lo que intente lograr, puede usar diferentes patrones incluso dentro de una biblioteca.
Si se supone que su función debe regresar inmediatamente después de iniciar algunas corrutinas, la "mejor práctica" es declarar su función como una extensión de CoroutineScope , de esa manera no tiene que usar el alcance global:
fun CoroutineScope.launchesAndReturnsImmediately() { // launch can be called because we are extending CoroutineScope launch { // some work } } Dicho esto, a menudo no necesita regresar de inmediato cuando está en una biblioteca, por lo que puede declarar sus funciones suspend , lo que es más fácil de entender por parte del consumidor. Múltiples opciones allí:
withContext para ejecutar en el grupo de subprocesos apropiado, o llamar a otras funciones de suspensióncoroutineScope para iniciar corrutinas secundarias y descomponer el trabajo, pero aún suspenda hasta que todas las corrutinas secundarias estén listassuspendCoroutine o suspendCancellableCoroutine