פרוטוקול Threading ב-CoroutineWorker

למשתמשי Kotlin, WorkManager מספק תמיכה ברמה הגבוהה ביותר לקורוטין. כדי לקבל מתחילים, צריך לכלול את work-runtime-ktx בקובץ gradle. במקום להאריך את התוקף של Worker, צריך להאריך את התקופה CoroutineWorker, שכוללת השעיה גרסה של doWork(). לדוגמה, אם רציתם ליצור CoroutineWorker פשוט כדי לבצע פעולות מסוימות ברשת, צריך לבצע את הפעולות הבאות:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        val data = downloadSynchronously("https://www.google.com")
        saveData(data)
        return Result.success()
    }
}

לתשומת ליבכם: CoroutineWorker.doWork() הוא חשבון בהוצאה מותאמת אישית. בניגוד ל-Worker, הקוד הזה לא פועל ב-Executor שצוין ב-Configuration. במקום זאת, ברירת המחדל היא Dispatchers.Default. אפשר להתאים אישית את זה בעזרת CoroutineContext משלך. בדוגמה שלמעלה, סביר להניח שתרצו לבצע את העבודה הזו ב-Dispatchers.IO, באופן הבא:

class CoroutineDownloadWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result {
        withContext(Dispatchers.IO) {
            val data = downloadSynchronously("https://www.google.com")
            saveData(data)
            return Result.success()
        }
    }
}

CoroutineWorker מטפל בעצירה אוטומטית על ידי ביטול הקורוטינים והפצת אותות הביטול. לא צריך לעשות שום דבר מיוחד לטיפול בתחנות עבודה.

הפעלת CoroutineWorker בתהליך אחר

אפשר גם לקשר עובד לתהליך ספציפי באמצעות RemoteCoroutineWorker יישום של ListenableWorker.

RemoteCoroutineWorker מקושר לתהליך ספציפי עם שני ארגומנטים נוספים שאתם מספקים כחלק מנתוני הקלט בתהליך היצירה של בקשת העבודה: ARGUMENT_CLASS_NAME וגם ARGUMENT_PACKAGE_NAME

הדוגמה הבאה ממחישה יצירה של בקשת עבודה שקשורה תהליך ספציפי:

Kotlin

val PACKAGE_NAME = "com.example.background.multiprocess"

val serviceName = RemoteWorkerService::class.java.name
val componentName = ComponentName(PACKAGE_NAME, serviceName)

val data: Data = Data.Builder()
   .putString(ARGUMENT_PACKAGE_NAME, componentName.packageName)
   .putString(ARGUMENT_CLASS_NAME, componentName.className)
   .build()

return OneTimeWorkRequest.Builder(ExampleRemoteCoroutineWorker::class.java)
   .setInputData(data)
   .build()

Java

String PACKAGE_NAME = "com.example.background.multiprocess";

String serviceName = RemoteWorkerService.class.getName();
ComponentName componentName = new ComponentName(PACKAGE_NAME, serviceName);

Data data = new Data.Builder()
        .putString(ARGUMENT_PACKAGE_NAME, componentName.getPackageName())
        .putString(ARGUMENT_CLASS_NAME, componentName.getClassName())
        .build();

return new OneTimeWorkRequest.Builder(ExampleRemoteCoroutineWorker.class)
        .setInputData(data)
        .build();

לכל RemoteWorkerService צריך להוסיף הגדרת שירות גם בקטע קובץ AndroidManifest.xml שלך:

<manifest ... >
    <service
            android:name="androidx.work.multiprocess.RemoteWorkerService"
            android:exported="false"
            android:process=":worker1" />

        <service
            android:name=".RemoteWorkerService2"
            android:exported="false"
            android:process=":worker2" />
    ...
</manifest>

דוגמיות