2026'da Android WorkManager: Arka Plan Görevleri, Kısıtlamalar ve Mülakat Soruları
Kotlin'de WorkManager 2.11 için kapsamlı rehber - temel kurulumdan kısıtlamalar ve iş zincirlerine, testlere ve mülakat sorularına kadar her şey.

Android WorkManager, uygulama yeniden başlatmaları ve cihaz yeniden başlatmaları boyunca kalıcı olan ertelenebilir, garantili arka plan işlerini yönetir. Android Jetpack'in bir parçası olarak yayınlanan WorkManager 2.11.2 (kararlı sürüm, Mart 2026), API 23+ üzerinde çalışan ve cihazın API seviyesine göre en iyi uygulamayı (JobScheduler, AlarmManager veya Firebase JobDispatcher) otomatik olarak seçen birleşik bir API sağlar.
WorkManager, garantili yürütme gerektiren görevler için kullanılmalıdır: log gönderme, veri senkronizasyonu, görüntü işleme. Süreç ölümünden sonra devam etmesi gerekmeyen anlık işler için Kotlin Coroutines tercih edilmelidir.
Kotlin Projesinde WorkManager 2.11 Kurulumu
Herhangi bir worker yazmadan önce bağımlılık tanımlanmalıdır. WorkManager 2.11+ minSdk 23 ve compileSdk 33 gerektirir.
dependencies {
val workVersion = "2.11.2"
implementation("androidx.work:work-runtime-ktx:$workVersion")
// Optional: for testing
androidTestImplementation("androidx.work:work-testing:$workVersion")
}work-runtime-ktx artifact'ı, CoroutineWorker aracılığıyla Kotlin uzantıları ve Coroutine desteği içerir. Temel kullanım için ek yapılandırma gerekmez: WorkManager kendini bir ContentProvider aracılığıyla otomatik olarak başlatır.
doWork() ile Basit Bir Worker Oluşturma
Bir Worker sınıfı doWork() metodunu override eder ve bir Result döndürür. Sistem bu metodu arka plan iş parçacığında çalıştırır.
class SyncWorker(
context: Context,
params: WorkerParameters
) : Worker(context, params) {
override fun doWork(): Result {
// Read input data
val userId = inputData.getString("user_id") ?: return Result.failure()
return try {
// Perform sync operation
val syncService = SyncService.getInstance(applicationContext)
syncService.syncUserData(userId)
Result.success()
} catch (e: IOException) {
// Retry on network errors
Result.retry()
} catch (e: Exception) {
// Permanent failure
Result.failure()
}
}
}Üç olası sonuç vardır: Result.success() tamamlanmayı işaret eder, Result.failure() yeniden denemeleri durdurur ve Result.retry() backoff politikasına göre yeniden planlar.
Suspend Fonksiyonlar için CoroutineWorker Kullanımı
İş suspend fonksiyonları (Retrofit çağrıları, Room sorguları) içerdiğinde, CoroutineWorker callback iç içe geçmesini ortadan kaldırır.
class UploadWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val imageUri = inputData.getString("image_uri")
?: return Result.failure()
// Progress reporting (visible in WorkInfo observers)
setProgress(workDataOf("status" to "compressing"))
val compressed = ImageCompressor.compress(imageUri)
setProgress(workDataOf("status" to "uploading"))
return try {
val response = ApiClient.imageService.upload(compressed)
val outputData = workDataOf("url" to response.imageUrl)
Result.success(outputData)
} catch (e: HttpException) {
if (e.code() in 500..599) Result.retry()
else Result.failure()
}
}
}CoroutineWorker.doWork() varsayılan olarak Dispatchers.Default üzerinde çalışır. Dispatcher değiştirmek için fonksiyon içinde withContext() kullanılmalıdır.
Koşullu Yürütme için Kısıtlamaları Tanımlama
Kısıtlamalar, koşullar karşılanana kadar işin çalışmasını engeller. Bu pil tasarrufu sağlar ve başarısız denemeleri önler.
fun scheduleUpload(context: Context, imageUri: String) {
val constraints = Constraints.Builder()
.setRequiredNetworkType(NetworkType.UNMETERED) // WiFi only
.setRequiresBatteryNotLow(true)
.setRequiresStorageNotLow(true)
.build()
val uploadRequest = OneTimeWorkRequestBuilder<UploadWorker>()
.setConstraints(constraints)
.setInputData(workDataOf("image_uri" to imageUri))
.setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
Duration.ofMinutes(1)
)
.addTag("upload")
.build()
WorkManager.getInstance(context)
.enqueueUniqueWork(
"upload_$imageUri",
ExistingWorkPolicy.KEEP,
uploadRequest
)
}Mevcut kısıtlamalar arasında ağ türü (CONNECTED, UNMETERED, METERED, NOT_ROAMING), pil seviyesi, şarj durumu, depolama alanı ve cihaz boşta durumu bulunur. WorkManager 2.10+ ayrıca hassas ağ kontrolü için ham NetworkRequest kabul eder.
Yaygın bir mülakat sorusu, enqueueUniqueWork'te KEEP ve REPLACE arasındaki farkı sorar. KEEP, aynı ada sahip iş varsa yeni istekleri yok sayar; REPLACE, mevcut işi iptal eder ve yeniden başlar. Yüklemelerde duplikasyonların bant genişliği israfına yol açtığı durumlarda KEEP, yalnızca en son verilerin önemli olduğu senkronizasyonlarda REPLACE kullanılır.
then() ve combine() ile İş İsteklerini Zincirleme
Karmaşık iş akışları sıralı ve paralel yürütme gerektirir. WorkManager, beginWith() ve then() kullanarak iş isteklerini zincirler.
fun processAndUploadImages(context: Context, imageUris: List<String>) {
val workManager = WorkManager.getInstance(context)
// Parallel compression workers
val compressRequests = imageUris.map { uri ->
OneTimeWorkRequestBuilder<CompressWorker>()
.setInputData(workDataOf("uri" to uri))
.build()
}
// Single upload worker runs after all compressions complete
val uploadRequest = OneTimeWorkRequestBuilder<BatchUploadWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.build()
// Cleanup runs after upload, regardless of success
val cleanupRequest = OneTimeWorkRequestBuilder<CleanupWorker>()
.build()
workManager
.beginWith(compressRequests) // Parallel
.then(uploadRequest) // Sequential
.then(cleanupRequest) // Sequential
.enqueue()
}Paralel worker'lardan gelen çıktı varsayılan olarak ArrayCreatingInputMerger ile birleştirilir. Sonraki worker tüm anahtar-değer çiftlerini alır ve yinelenen anahtarlar için diziler oluşturulur.
Android mülakatlarında başarılı olmaya hazır mısın?
İnteraktif simülatörler, flashcards ve teknik testlerle pratik yap.
PeriodicWorkRequest ile Periyodik İş Planlama
PeriodicWorkRequest, minimum 15 dakikalık aralıklarla (Android bu limiti zorlar) tekrar tekrar yürütülür.
fun scheduleDailySync(context: Context) {
val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(
repeatInterval = 6,
repeatIntervalTimeUnit = TimeUnit.HOURS,
flexTimeWindow = 30,
flexTimeUnit = TimeUnit.MINUTES
)
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.addTag("periodic_sync")
.build()
WorkManager.getInstance(context)
.enqueueUniquePeriodicWork(
"daily_sync",
ExistingPeriodicWorkPolicy.UPDATE,
syncRequest
)
}Esneklik penceresi, WorkManager'ın işi diğer görevlerle gruplandırmasına olanak tanır ve pil verimliliğini artırır. 30 dakikalık esneklik penceresi ile 6 saatlik aralık, yürütmenin önceki çalışmadan 5:30 ile 6:00 arasında bir zamanda gerçekleşeceği anlamına gelir.
LiveData ve Flow ile İş Durumunu Gözlemleme
WorkManager, iş durumunu WorkInfo aracılığıyla sunar. LiveData veya Kotlin Flow kullanılarak gözlemlenebilir.
class UploadViewModel(application: Application) : AndroidViewModel(application) {
private val workManager = WorkManager.getInstance(application)
// Flow-based observation
fun observeUpload(workId: UUID): Flow<WorkInfo?> {
return workManager.getWorkInfoByIdFlow(workId)
}
// Check if any upload is running
val activeUploads: Flow<List<WorkInfo>> =
workManager.getWorkInfosByTagFlow("upload")
.map { workInfos ->
workInfos.filter { it.state == WorkInfo.State.RUNNING }
}
}
// In Compose UI
@Composable
fun UploadProgress(workId: UUID, viewModel: UploadViewModel) {
val workInfo by viewModel.observeUpload(workId)
.collectAsState(initial = null)
when (workInfo?.state) {
WorkInfo.State.RUNNING -> {
val status = workInfo?.progress?.getString("status") ?: "working"
CircularProgressIndicator()
Text(status)
}
WorkInfo.State.SUCCEEDED -> {
val url = workInfo?.outputData?.getString("url")
Text("Uploaded: $url")
}
WorkInfo.State.FAILED -> Text("Upload failed")
else -> {}
}
}İş durumları bir yaşam döngüsü izler: ENQUEUED, RUNNING, SUCCEEDED/FAILED/CANCELLED, BLOCKED (bağımlılıklar bekleniyor).
WorkManager 2.12 Work Metrics API
WorkManager 2.12.0-rc01 (Ağustos 2026), yürütme geçmişini izlemek için WorkMetricsInfo sunar.
class MetricsRepository(private val context: Context) {
private val workManager = WorkManager.getInstance(context)
suspend fun getWorkerMetrics(workerName: String): List<WorkMetricsInfo> {
val query = WorkMetricsQuery.Builder()
.setWorkerClassName(workerName)
.setLimit(100)
.build()
return workManager.getWorkMetrics(query)
}
fun analyzeFailures(metrics: List<WorkMetricsInfo>): Map<Int, Int> {
// Count stop reasons
return metrics
.flatMap { it.stopReasonCounts.entries }
.groupBy { it.key }
.mapValues { entry -> entry.value.sumOf { it.value } }
}
}Metrikler yürütme süresini, yeniden deneme sayaçlarını, durdurma nedenlerini ve zaman damgalarını içerir. API, özel loglama altyapısı olmadan üretimdeki aralıklı hataların debug edilmesini sağlar.
WorkMetricsInfo verileri varsayılan olarak 7 gün sonra temizlenir. Saklama süresi Configuration.Builder().setWorkMetricsRetentionDuration() ile yapılandırılabilir.
WorkManagerTestInitHelper ile Worker'ları Test Etme
Worker'ların birim testi work-testing artifact'ını gerektirir. TestListenableWorkerBuilder, worker'ları kuyruğa almadan oluşturur.
@RunWith(AndroidJUnit4::class)
class SyncWorkerTest {
private lateinit var context: Context
@Before
fun setup() {
context = ApplicationProvider.getApplicationContext()
val config = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(SynchronousExecutor())
.build()
WorkManagerTestInitHelper.initializeTestWorkManager(context, config)
}
@Test
fun syncWorker_withValidUserId_succeeds() = runTest {
val inputData = workDataOf("user_id" to "123")
val worker = TestListenableWorkerBuilder<SyncWorker>(context)
.setInputData(inputData)
.build()
val result = worker.doWork()
assertThat(result).isEqualTo(ListenableWorker.Result.success())
}
@Test
fun syncWorker_withoutUserId_fails() = runTest {
val worker = TestListenableWorkerBuilder<SyncWorker>(context)
.build()
val result = worker.doWork()
assertThat(result).isEqualTo(ListenableWorker.Result.failure())
}
}Kısıtlamaları ve zincirlemeyi doğrulayan entegrasyon testleri için TestDriver, kısıtlama karşılama ve zaman geçişi simülasyonu yapar.
WorkManager Hakkında Yaygın Mülakat Soruları
Teknik mülakatlar sıklıkla WorkManager'ın garantilerini ve ödünleşimlerini test eder. Bu sorular orta ve üst düzey Android mülakatlarında görülür.
S: Uygulama sonlandırıldığında WorkRequest'e ne olur?
WorkManager iş isteklerini bir Room veritabanında saklar. Uygulama yeniden başladığında veya sistem kısıtlama karşılandığını bildirdiğinde, bekleyen iş devam eder. Bu garanti, WorkManager'ı süreçle birlikte ölen CoroutineScope işinden ayırır.
S: WorkManager AlarmManager'dan nasıl farklıdır?
AlarmManager kesin zamanlı alarmlar planlar ve belirli saat zamanlarında kod çalıştırır. WorkManager, kısıtlamalar karşılandığında çalışan ertelenebilir iş planlar, kesin zamanlama garantisi yoktur. Kullanıcıya görünür alarmlar için AlarmManager, arka plan veri işleme için WorkManager kullanılır.
S: WorkManager işi hemen çalıştırabilir mi?
Evet, setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) ile. Hızlandırılmış iş istekleri API 31+ üzerinde ön plan hizmet slotunu veya daha eski API'lerde JobScheduler.setImportantWhileForeground() kullanır. Kota limitleri geçerlidir, bu nedenle OutOfQuotaPolicy geri dönüş davranışını tanımlar.
S: Tüm bekleyen yüklemeler nasıl iptal edilir?
WorkManager.getInstance(context).cancelAllWorkByTag("upload")Etiketler toplu işlemleri etkinleştirir. Alternatif olarak, cancelUniqueWork("name") belirli bir zinciri iptal eder.
Backoff Politikaları ile Sistem Kaynaklı Durmaları Yönetme
Sistem bir worker'ı durdurduğunda (pil optimizasyonu, bellek baskısı), backoff politikası yeniden deneme zamanlamasını belirler.
val request = OneTimeWorkRequestBuilder<UploadWorker>()
.setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
Duration.ofSeconds(30) // Initial delay, minimum 10 seconds
)
.setBackoffOnSystemInterruption(true) // New in 2.11
.build()Üstel backoff her yeniden denemede gecikmeyi ikiye katlar: 30s, 60s, 120s, maksimum 5 saate kadar. Doğrusal backoff her seferinde başlangıç gecikmesini ekler: 30s, 60s, 90s. WorkManager 2.11'deki yeni setBackoffOnSystemInterruption() bayrağı, durmaya sistem (worker değil) neden olduğunda bile backoff uygular.
Pratik yapmaya başla!
Mülakat simülatörleri ve teknik testlerle bilgini test et.
Üretim WorkManager Kullanımı için Temel Çıkarımlar
- Suspend fonksiyonları çağırırken
WorkeryerineCoroutineWorkertercih edilmelidir. İş parçacıklarını bloke etmekten kaçınır ve mevcut coroutine koduyla entegre olur. - Yinelenen işi önlemek için
enqueueUniqueWork()kullanılmalıdır. Idempotent işlemler içinKEEP, yalnızca en son isteğin önemli olduğu durumlar içinREPLACEseçilmelidir. - Her isteğe anlamlı etiketler eklenmelidir. Etiketler, iş zincirleri boyunca gözlem, iptal ve debug işlemlerini etkinleştirir.
- Worker'ları
TestListenableWorkerBuilderile izole olarak test edin, ardından zincirleriTestDriverkısıtlama simülasyonu ile test edin. - WorkManager 2.12'nin
WorkMetricsInfoAPI'si yürütme geçmişi sağlar. Üretimdeki yeniden deneme kalıplarını ve durdurma nedenlerini debug etmek için kullanılmalıdır. - Kısıtlamalar pil tasarrufu sağlar. Ağ eksikliği nedeniyle başarısız olan bir worker, yeniden deneme girişimlerinde CPU döngüleri harcar ve enerji tüketir.
- Periyodik iş için 15 dakikalık minimum Android tarafından zorlanır, WorkManager tarafından değil. Periyodik görevler bu aralığa toleranslı olacak şekilde tasarlanmalıdır.
Android kodundaki hatayı bulabilir misin?
Gerçek bir kod parçası, gizli bir hata, günde bir deneme. Denemek için hesap gerekmez.

Yazan:
Anthony Fillion-MailletSharpSkill kurucusu
10 yılı aşkın süredir fullstack geliştirici. SharpSkill’i yönetiyor ve burada yayımlanan her şeyden sorumlu.
22 Ağustos 2026 tarihinde güncellendi
Etiketler
Paylaş
İlgili makaleler

2026'da Jetpack Navigation Compose: Type-Safe Navigasyon ve Mülakat Soruları
Type-safe navigasyon, gelişmiş desenler ve Android geliştiricileri için mülakat soruları içeren kapsamlı Jetpack Navigation Compose rehberi.

Android 2026'da Room Database: Migration, İlişkiler ve Coroutines
Android 2026'da Room Database hakkında kapsamlı rehber - şema migrasyonları, entity ilişkileri, Kotlin Coroutines entegrasyonu ve en iyi uygulama pratikleri.

Kotlin Flow, StateFlow ve SharedFlow: 2026'da Android Mülakat Soruları
Android mülakatçılarının 2026'da sorduğu Kotlin Flow, StateFlow ve SharedFlow soruları; net yanıtlar, bir karşılaştırma tablosu ve üretime hazır kod ile birlikte.