رشته‌بندی در Worker

وقتی از Worker استفاده می‌کنید، WorkManager به‌طور خودکار Worker.doWork() را در رشته پس‌زمینه فراخوانی می‌کند. رشته پس‌زمینه از Executor مشخص‌شده در Configuration WorkManager می‌آید. به‌طور پیش‌فرض، WorkManager یک Executor برای شما راه‌اندازی می‌کند—اما می‌توانید آن را سفارشی‌سازی کنید. برای مثال، می‌توانید یک Executor پس‌زمینه موجود را در برنامه‌تان هم‌رسانی کنید، یک Executor تک‌رشته‌ای ایجاد کنید تا مطمئن شوید همه کارهای پس‌زمینه شما به‌صورت متوالی اجرا می‌شوند، یا حتی یک Executor سفارشی مشخص کنید. برای سفارشی‌سازی Executor، حتماً WorkManager را به‌صورت دستی مقداردهی اولیه کنید.

هنگام پیکربندی دستی WorkManager، می‌توانید Executor خود را به‌صورت زیر مشخص کنید:

کاتلین

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

جاوا

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

در اینجا نمونه‌ای از یک Worker ساده آورده شده است که محتوای یک صفحه وب را ۱۰۰ بار بارگیری می‌کند:

کاتلین

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()
    }
}

جاوا

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() یک فراخوانی همگام است—انتظار می‌رود که کل کار پس‌زمینه‌تان را به‌صورت مسدودکننده انجام دهید و آن را تا زمان خروج از روش به‌پایان برسانید. اگر یک API ناهمگام را در doWork() فراخوانی کنید و یک Result برگردانید، ممکن است فراخوانی شما به‌درستی عمل نکند. اگر در این موقعیت قرار گرفتید، از ListenableWorker استفاده کنید (رشته‌بندی در ListenableWorker را ببینید).

وقتی Worker درحال اجرا به هر دلیلی متوقف شود، تماسی با Worker.onStopped() دریافت می‌کند. این روش را لغو کنید یا Worker.isStopped() را فراخوانی کنید تا درصورت لزوم، کدتان را بررسی کنید و منابع را آزاد کنید. وقتی Worker در مثال بالا متوقف می‌شود، ممکن است در میان حلقه بارگیری موارد باشد و حتی با وجود متوقف شدن، به این کار ادامه دهد. برای بهینه‌سازی این رفتار، می‌توانید کاری شبیه به این انجام دهید:

کاتلین

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()
    }
}

جاوا

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 نادیده گرفته خواهد شد.