runBlocking en Kotlin Coroutines con ejemplo

Requisito previo:

Como se sabe, cuando el usuario llama a la función delay() en cualquier rutina , no bloqueará el subproceso en el que se está ejecutando, mientras se llama a la función delay() , se pueden realizar otras operaciones como actualizar la interfaz de usuario y muchas más. cosas. Como la función de retraso es una función de suspensión, debe llamarse desde la rutina u otra función de suspensión.

Definición de la función runBlocking() 

Según la documentación oficial, la función runBlocking() puede definirse como:

runBlocking es una función de rutina. Al no proporcionar ningún contexto, se ejecutará en el subproceso principal. Ejecuta una nueva rutina y bloquea el subproceso actual interrumpible hasta su finalización. Esta función no debe usarse desde una rutina. Está diseñado para unir el código de bloqueo regular con las bibliotecas que están escritas en estilo de suspensión, para usarse en las funciones principales y en las pruebas.

Kotlin

// sample program in android studio to demonstrate coroutines
package com.example.gfgcoroutines
  
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
  
class MainActivity : AppCompatActivity() {
    val TAG:String="Main Activity"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        GlobalScope.launch(Dispatchers.Main) {
            delay(3000)
            Log.d(TAG,"User is in the Global Scope ")
            Toast.makeText(applicationContext,"User is in the Global Scope ",Toast.LENGTH_SHORT).show()
        }
        Log.d(TAG,"User is not in the Global Scope ")
        Toast.makeText(applicationContext,"User is not in the Global Scope ",Toast.LENGTH_SHORT).show()
    }
}

Salida de registro:

Registro de salida del programa anterior (las marcas de tiempo en segundos se muestran mediante un círculo ovalado en la imagen)

Log output

Como se puede ver en la salida del registro, el «Usuario está en el alcance global» se imprime después del registro «El usuario no está en el alcance global», lo que muestra que GlobalScope inicia una corrutina, que no bloquea el principal subproceso, y las otras operaciones se pueden realizar mientras el tiempo de retraso se acaba. Pero cuando alguien quiere llamar solo a la función de suspensión y no necesita el comportamiento de la rutina, puede llamar a la función de suspensión desde runBlocking. Entonces, cuando uno quiere llamar a cualquier función de suspensión como delay() y no le importa la naturaleza asíncrona, puede usar la función runBlocking. La diferencia entre llamar a la función de suspensión desde GlobalScope.launch{ } y llamar a la función de suspensión (por ejemplo, delay()) desde runBlocking{ }es que runBlocking bloqueará el subproceso principal o el subproceso en el que se usa y GlobalScope.launch{ } no bloqueará el subproceso principal, en este caso, las operaciones de la interfaz de usuario se pueden realizar mientras el subproceso se retrasa.

Otro caso de uso de runBlocking es para probar JUnit, en el que se necesita acceder a la función de suspensión desde dentro de la función de prueba. Un caso también usa runBlocking para aprender las corrutinas en profundidad para descubrir cómo funcionan detrás de escena. Veamos en los ejemplos a continuación cómo funciona realmente runBlocking:

Kotlin

package com.example.gfgcoroutines
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
  
class MainActivity : AppCompatActivity() 
{
    val TAG="Main Activity"
    override fun onCreate(savedInstanceState: Bundle?) 
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
          
        Log.d(TAG,"Before run-blocking")
            runBlocking 
              {
              Log.d(TAG,"just entered into the runBlocking ")
              delay(5000)
  
              Log.d(TAG,"start of the run-blocking")
              Log.d(TAG,"End of the runBlocking")
            }
        Log.d(TAG,"after the run blocking")
    }
}

Salida de registro:

Registro de salida del programa anterior (las marcas de tiempo en segundos se muestran mediante un círculo ovalado en la imagen)

Log output

El círculo ovalado redondo en la salida del registro anterior muestra las marcas de tiempo en las que se imprime la salida del registro. Se puede ver claramente que cuando «recién ingresado en el bloqueo de ejecución» se encuentra el retraso de 5 segundos, por lo que otras operaciones no se pueden realizar y deben esperar 5 segundos. La declaración de registro «después del bloqueo de ejecución», que también está fuera de la función de bloqueo de ejecución, tiene que esperar a que la función de bloqueo de ejecución completa termine su trabajo. Tomemos otro ejemplo e intentemos aprender cómo funciona runBlocking y cómo se pueden iniciar diferentes rutinas dentro de él.

Kotlin

package com.example.gfgcoroutines
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Toast
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
  
class MainActivity : AppCompatActivity() 
{
    val TAG="Main Activity"
    override fun onCreate(savedInstanceState: Bundle?) 
    {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
          
        Log.d(TAG,"Before run-blocking")
             runBlocking 
               {
              Log.d(TAG,"just entered into the runBlocking ")
              delay(5000)
              launch(Dispatchers.IO)
             {
                delay(3000L)
                Log.d(TAG,"Finished to coroutine 1")
             }
  
             launch(Dispatchers.IO)
             {
                delay(3000L)
                Log.d(TAG,"Finished to coroutine 2")
             }
              Log.d(TAG,"start of the run-blocking")
              Log.d(TAG,"End of the runBlocking")
             }
         Log.d(TAG,"after the run blocking")
         GlobalScope.launch 
         {
            Log.d(TAG,"Logging in the globalScope")
         }
    }
}

Salida de registro:

Registro de salida del programa anterior (las marcas de tiempo en segundos se muestran mediante un círculo ovalado en la imagen)

Log output

Se puede ver en la salida de registro anterior que tanto GlobalScope como el lanzamiento se ejecutarán después del retraso de runBlocking. Como tanto la corrutina que se inicia dentro de runBlocking con la función de lanzamiento se ejecutará dentro del mismo subproceso, parece que ambas corrutinas se ejecutan en paralelo, pero no es posible ya que ambas se ejecutan en el mismo subproceso, pero se ejecutan en una manera asincrónica. Por lo tanto, se puede decir que los usuarios deben usar coroutine runBlocking solo cuando el usuario quiere hacer una prueba JUnit o quiere llamar solo a las funciones de suspensión.

Publicación traducida automáticamente

Artículo escrito por lavishgarg26 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *