Worker 中的執行緒

使用 Worker 時,WorkManager 會在背景執行緒上自動呼叫 Worker.doWork()。背景執行緒來自在 WorkManager 的 Configuration 中指定的 Executor。根據預設,WorkManager 會為您設定 Executor,但您也可以自訂這項設定。舉例來說,您可以在應用程式中分享現有的背景執行工具、建立單一執行緒 Executor,確保所有背景作業依序執行,甚至指定自訂 Executor。如要自訂 Executor,請務必手動初始化 WorkManager。

手動設定 WorkManager 時,您可以按照下列方式指定 Executor

Kotlin

WorkManager.initialize(
    context,
    Configuration.Builder()
         // Uses a fixed thread pool of size 8 threads.
        .setExecutor(Executors.newFixedThreadPool(8))
        .build())

Java

WorkManager.initialize(
    context,
    new Configuration.Builder()
        .setExecutor(Executors.newFixedThreadPool(8))
        .build());

此為下載網頁內容 100 次的簡單 Worker 範例:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }
        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; i++) {
            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }

}

請注意,Worker.doWork() 是同步呼叫,建議您以全面封鎖的方式執行所有背景作業,並在方法退出時完成作業。如果您在 doWork() 中呼叫非同步 API,並回傳 Result,則回呼可能無法正常運作。如果遇到這種情況,請考慮使用 ListenableWorker (請參閱「ListenableWorker 中的執行緒」)。

如果目前執行中的 Worker 因任何原因而停止運作,則會呼叫 Worker.onStopped()。請覆寫此方法或呼叫 Worker.isStopped() 以檢查程式碼,並視需要釋出資源。當上述範例中的 Worker 停止時,該項目可能會位於下載項目的循環中間,即使該程序已停止,仍會繼續執行。如要最佳化此行為,您可以執行下列操作:

Kotlin

class DownloadWorker(context: Context, params: WorkerParameters) : Worker(context, params) {

    override fun doWork(): ListenableWorker.Result {
        repeat(100) {
            if (isStopped) {
                break
            }

            try {
                downloadSynchronously("https://www.google.com")
            } catch (e: IOException) {
                return ListenableWorker.Result.failure()
            }

        }

        return ListenableWorker.Result.success()
    }
}

Java

public class DownloadWorker extends Worker {

    public DownloadWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        for (int i = 0; i < 100; ++i) {
            if (isStopped()) {
                break;
            }

            try {
                downloadSynchronously("https://www.google.com");
            } catch (IOException e) {
                return Result.failure();
            }
        }

        return Result.success();
    }
}

停止 Worker 並不影響您從 Worker.doWork() 回傳的內容;請忽略 Result