Práctica de WorkManager en Kotlin

WorkManager es una biblioteca de extensión de Android Jetpack que le permite planificar fácilmente tareas que pueden posponerse y ser asincrónicas pero deben ejecutarse de manera confiable. Para la mayoría de las tareas en segundo plano, el uso de WorkManager es actualmente la mejor práctica en la plataforma Android.

  • WorkManager

    https://developer.android.google.cn/topic/libraries/architecture/workmanager/

  • Jetpack de Android

    https://developer.android.google.cn/jetpack/

Hasta ahora se ha discutido la serie WorkManager:

 

En este artículo, discutiremos:

  • Cómo utilizar WorkManager en Kotlin

  • CoroutineWorker 类

  • Cómo utilizar TestListenableWorkerBuilder para probar su clase CoroutineWorker

  • CoroutineWorker

    https://developer.android.google.cn/reference/kotlin/androidx/work/CoroutineWorker

  • TestListenableWorkerBuilder

    https://developer.android.google.cn/reference/androidx/work/testing/TestListenableWorkerBuilder

Versión Kotlin de WorkManager

El código de muestra de este artículo está escrito en Kotlin y usa la biblioteca KTX (Extensiones de Kotlin). La versión KTX de WorkManager proporciona funciones de extensión de Kotlin más concisas e idiomáticas. Como se describe en el registro de versiones de WorkManager, solo necesita agregar la dependencia androidx.work:work-runtime-ktx al archivo build.gradle para usar la versión KTX de WorkManager. Este componente contiene CoroutineWorker y otros métodos de extensión de WorkManager útiles.

  • Biblioteca KTX

    https://developer.android.google.cn/kotlin/ktx

  • Publicar registro

    https://developer.android.google.cn/jetpack/androidx/releases/work

Más conciso e idiomático

Cuando necesita construir un objeto de datos y necesita pasarlo o regresar de la clase Worker, la versión KTX de WorkManager proporciona una especie de azúcar sintáctico. En este caso, el código implementado en la sintaxis de Java es el siguiente:

Data myData = new Data.Builder()
                      .putInt(KEY_ONE_INT, aInt)
                      .putIntArray(KEY_ONE_INT_ARRAY, aIntArray)
                      .putString(KEY_ONE_STRING, aString)
                      .build();

En Kotlin, podemos usar la función auxiliar workDataOf para escribir el código de forma más concisa:

inline fun workDataOf(vararg pairs: Pair<String, Any?>): Data
  • workDataOf

    https://developer.android.google.cn/reference/kotlin/androidx/work/package-summary#workdataof

Por lo tanto, la expresión Java anterior se puede reescribir como:

val data = workDataOf(
        KEY_MY_INT to myIntVar,
        KEY_MY_INT_ARRAY to myIntArray,
        KEY_MY_STRING to myString
    )

CoroutineWorker

Además de las clases Worker (Worker, ListenableWorker y RxWorker) que se pueden implementar en Java, existe la única clase Work que se puede implementar usando Kotlin coroutines-CoroutineWorker.

  • Trabajador

    https://developer.android.google.cn/reference/androidx/work/Worker.html

  • Trabajador escuchable

    https://developer.android.google.cn/reference/androidx/work/ListenableWorker

  • RxWorker

    https://developer.android.google.cn/reference/androidx/work/RxWorker.html

  • Corutina de Kotlin

    https://kotlinlang.org/docs/reference/coroutines-overview.html

  • CoroutineWorker

    https://developer.android.google.cn/reference/kotlin/androidx/work/CoroutineWorker.html

La principal diferencia entre la clase Worker y la clase CoroutineWorker es: El método doWork () de la clase CoroutineWorker es una función de suspensión que puede realizar tareas asincrónicas, mientras que el método doWork () de la clase Worker solo puede realizar tareas síncronas. Otra característica de CoroutineWorker es que puede manejar automáticamente la suspensión y cancelación de tareas, y la clase Worker necesita implementar el método onStopped () para manejar estas situaciones.

 

Para obtener información de contexto completa, consulte la documentación oficial para subprocesos en WorkManager. Aquí, quiero centrarme en lo que es CoroutineWorker y cubrir algunas diferencias pequeñas pero importantes, así como una comprensión profunda de cómo usar las nuevas funciones de prueba introducidas en WorkManager v2.1 para probar su clase CoroutineWorker.

  • Procesamiento de subprocesos en WorkManager

    https://developer.android.google.cn/topic/libraries/architecture/workmanager/advanced/threading

Como se escribió anteriormente, CoroutineWorker # doWork () es solo una función de suspensión. Se inicia en Dispatchers. De forma predeterminada:

class MyWork(context: Context, params: WorkerParameters) :
        CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
return try {
            // 做点什么
            Result.success()
        } catch (error: Throwable) {
            Result.failure()
        }
    }
}
  • CoroutineWorker # doWork ()

    https://developer.android.google.cn/reference/kotlin/androidx/work/CoroutineWorker.html#dowork

Debe recordarse que esta es la diferencia fundamental al usar CoroutineWorker en lugar de Worker o ListenableWorker:

A diferencia de Worker, este código no se ejecutará en el Ejecutor especificado en la Configuración del WorkManager.

Como se acaba de decir, CoroutineWorker # doWork () se inicia en Dispatchers.De forma predeterminada. Puede usar withContext () para personalizar esta configuración.

class MyWork(context: Context, params: WorkerParameters) :
        CoroutineWorker(context, params) {
override suspend fun doWork(): Result = withContext(Dispatchers.IO) {
return try {
            // 做点什么
            Result.success()
        } catch (error: Throwable) {
            Result.failure()
        }
    }
}

Rara vez es necesario cambiar el Dispatcher utilizado por CoroutineWorker, porque Dispatchers.Default puede satisfacer las necesidades de la mayoría de situaciones.

Para aprender a usar WorkManager en Kotlin, puede probar este codelab.

  • codelab

    https://codelabs.developers.google.com/codelabs/android-workmanager-kt/

Prueba la clase Worker

WorkManager tiene varias clases de herramientas adicionales que pueden probar fácilmente su trabajo. Puede obtener más información sobre esto en la página de documentación de prueba de WorkManager y la nueva guía para realizar pruebas con WorkManager 2.1.0. La implementación original de la herramienta de prueba hace posible personalizar el WorkManager, de modo que podamos hacerlo aparecer como una ejecución sincrónica, y luego podemos usar WorkManagerTestInitHelper # getTestDriver () para simular retrasos y probar tareas periódicas.

  • Página de documentación de prueba de WorkManager

    https://developer.android.google.cn/topic/libraries/architecture/workmanager/how-to/testing

  • Utilice WorkManager 2.1.0 para realizar pruebas

    https://developer.android.google.cn/topic/libraries/architecture/workmanager/how-to/testing-210

  • WorkManagerTestInitHelper # getTestDriver ()

    https://developer.android.google.cn/reference/kotlin/androidx/work/testing/WorkManagerTestInitHelper#gettestdriver

Se agrega una nueva clase de herramienta en WorkManager v2.1: TestListenableWorkerBuilder, que presenta una nueva forma de probar la clase Worker.

 

Esta es una actualización muy importante para la clase CoroutineWorker, porque puede ejecutar la clase Worker directamente a través de TestListenableWorkerBuilder para probar si su lógica es correcta.

@RunWith(JUnit4::class)
class MyWorkTest {
    private lateinit var context: Context
    @Before
    fun setup() {
        context = ApplicationProvider.getApplicationContext()
    }
    @Test
    fun testMyWork() {
        // 获取 ListenableWorker 的实例
        val worker = 
            TestListenableWorkerBuilder<MyWork>(context).build()
        // 同步的运行 worker
        val result = worker.startWork().get()
        assertThat(result, `is`(Result.success()))
    }
}

El punto aquí es que puede obtener el resultado de ejecución de CoroutineWorker sincrónicamente, y luego puede verificar directamente si el comportamiento lógico de la clase Worker es correcto.

 

Utilice TestListenableWorkerBuilder para pasar datos de entrada a Worker o configure runAttemptCount, que es muy útil para probar la lógica de reintento dentro de Worker.

 

Por ejemplo, si desea cargar algunos datos en el servidor, puede agregar alguna lógica de reintento teniendo en cuenta los posibles problemas de conexión:

class MyWork(context: Context, params: WorkerParameters) :
        CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {
        val serverUrl = inputData.getString("SERVER_URL")
        return try {
            // 通过 URL 做点什么
            Result.success()
        } catch (error: TitleRefreshError) {
            if (runAttemptCount <3) {
                Result.retry()
            } else {
                Result.failure()
            }
        }
    }
}

Luego, puede usar TestListenableWorkerBuilder en la prueba para probar si la lógica de reintento es correcta:

@Test
fun testMyWorkRetry() {
    val data = workDataOf("SERVER_URL" to "[http://fake.url](http://fake.url)")
    // 获取 ListenableWorker,并将 RunAttemptCount 设置为 2
    val worker = TestListenableWorkerBuilder<MyWork>(context)   
                     .setInputData(data)
                     .setRunAttemptCount(2)
                     .build()
    // 启动同步执行的任务
    val result = worker.startWork().get()
    assertThat(result, `is`(Result.retry()))
}
@Test
fun testMyWorkFailure() {
    val data = workDataOf("SERVER_URL" to "[http://fake.url](http://fake.url)")
    // 获取 ListenableWorker,并将 RunAttemptCount 设置为 3
    val worker = TestListenableWorkerBuilder<MyWork>(context)
                     .setInputData(data)
                     .setRunAttemptCount(3)
                     .build()
    // 启动同步执行的任务
    val result = worker.startWork().get()
    assertThat(result, `is`(Result.failure()))
}

para resumir

Con el lanzamiento de WorkManager v2.1 y las nuevas funciones en workManager-testing, CoroutineWorker brilla por su simplicidad y facilidad de uso. Ahora puede probar la clase Worker muy fácilmente, y la experiencia general de usar WorkManager en Kotlin también es muy buena.

 

Si no ha utilizado CoroutineWorker y otras extensiones incluidas en workmanager-runtime-ktx en su proyecto, se recomienda encarecidamente que las utilice en su proyecto. Al desarrollar con Kotlin (que se ha convertido en mi rutina diaria), esta es mi forma preferida de usar WorkManager.

 

Espero que este artículo sea útil para usted. Puede dejar un mensaje en el área de comentarios para compartir sus ideas o preguntas sobre el uso de WorkManager.

Recursos relacionados con WorkManager

  • Guía para desarrolladores | Subprocesos en WorkManager

    https://developer.android.google.cn/topic/libraries/architecture/workmanager/

  • Guía de referencia | androidx.work

    https://developer.android.google.cn/reference/androidx/work/package-summary

  • Codelab | Use WorkManager para manejar tareas en segundo plano

    https://codelabs.developers.google.com/codelabs/android-workmanager

  • Rastreador de problemas públicos de WorkManager

    https://issuetracker.google.com/issues?q=componentid:409906

  • Registro de versiones | WorkManager

    https://developer.android.google.cn/jetpack/androidx/releases/work

  • Etiqueta [Android-workmanager] de Stack Overflow

    https://stackoverflow.com/questions/tagged/android-workmanager

  • Código fuente de WorkManager (parte de AOSP)

    https://android.googlesource.com/platform/frameworks/support/+/master/work


Lectura recomendada




 Haga clic en la pantalla al final leer leer el artículo original  | Ver documentos chinos oficiales de Android - Usar tareas programadas de WorkManager  


Supongo que te gusta

Origin blog.csdn.net/jILRvRTrc/article/details/108819455
Recomendado
Clasificación