WorkManager
Android’de bazı işlemler vardır ki kesintisiz ve garantiye yakın şekilde çalışması gerekir. İşte bu noktada WorkManager devreye girer.
WorkManager

Android’de bazı işlemler vardır ki kesintisiz ve garantiye yakın şekilde çalışması gerekir. İşte bu noktada WorkManager devreye girer.
WorkManager, Android Jetpack kütüphanesinin bir parçasıdır ve özellikle aşağıdaki senaryolar için idealdir:
- Uygulama kapansa bile çalışması gereken işler
- Cihaz yeniden başlasa bile devam etmesi gereken işlemler
- Network sonradan geldiğinde tetiklenmesi gereken görevler
Ne zaman kullanılır?
WorkManager genellikle şu işlemler için tercih edilir:
- Log gönderme
- Veri senkronizasyonu
- Fotoğraf upload etme
- Cache temizleme
Kullanılan Teknolojiler
Bu örnekte aşağıdaki bileşenleri birlikte kullanacağız:
- Hilt → Dependency Injection
- ViewModel → Lifecycle-aware state yönetimi
- Kotlin Coroutines → Asenkron işlemler
- WorkManager → Garantili background tasks
Dependency Kurulumu
// root build.gradle (project-level)
plugins {
id("com.google.dagger.hilt.android") version "2.51.1" apply false
}
// app/build.gradle.kts
plugins {
id("com.google.dagger.hilt.android")
id("kotlin-kapt")
}
dependencies {
// Hilt
implementation("com.google.dagger:hilt-android:2.51.1")
kapt("com.google.dagger:hilt-compiler:2.51.1")
// ViewModel + Compose
implementation("androidx.hilt:hilt-navigation-compose:1.2.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1")
// WorkManager
implementation("androidx.work:work-runtime-ktx:2.9.0")
// Hilt + WorkManager
implementation("androidx.hilt:hilt-work:1.2.0")
kapt("androidx.hilt:hilt-compiler:1.2.0")
}
// project-level (alternatif kullanım)
buildscript {
dependencies {
classpath("com.google.dagger:hilt-android-gradle-plugin:2.51.1")
}
}
Mimari Yaklaşım
Bu örnekte WorkManager tetikleme işlemini ViewModel üzerinden yöneteceğiz.
Bunun için:
- SyncScheduler adında bir interface oluşturacağız
- Bunun implementasyonu olan SyncSchedulerImpl ile WorkManager işlemini başlatacağız
SyncScheduler Implementasyonu
interface SyncScheduler {
fun scheduleOneTimeSync()
}
class SyncSchedulerImpl @Inject constructor(
@ApplicationContext private val context: Context
) : SyncScheduler {
override fun scheduleOneTimeSync() {
val request = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
30,
TimeUnit.SECONDS
)
.build()
WorkManager.getInstance(context).enqueueUniqueWork(
"sync_work",
ExistingWorkPolicy.KEEP,
request
)
}
}
Önemli Noktalar
1. Network Constraint
setRequiredNetworkType(NetworkType.CONNECTED)
Bu ayar sayesinde:
- İş sadece internet bağlantısı varsa çalışır
- Network sonradan gelirse otomatik olarak tetiklenir
2. Retry Mekanizması (Backoff)
setBackoffCriteria(
BackoffPolicy.EXPONENTIAL,
30,
TimeUnit.SECONDS
)
Bu yapı, iş başarısız olduğunda tekrar deneme stratejisini belirler.
EXPONENTIAL:
- 30 sn
- 60 sn
- 120 sn
- 240 sn
Fail durumunda süre katlanarak artar.
LINEAR:
- 30 sn
- 60 sn
- 90 sn
- 120 sn
Fail durumunda süre sabit artışla ilerler.
3. Küçük ama önemli detay
Buradaki 30 saniye değeri:
- İlk retry için bekleme süresidir
- İlk çalışmayı etkilemez
Kritik Nokta: Duplicate Work Problemi
enqueueUniqueWork(...)
Eğer bunu kullanmazsan:
👉 Aynı iş birden fazla kez enqueue edilir 👉 Arka planda gereksiz duplicate işlemler oluşur
Bu yüzden production’da unique work kullanmak kritik.
Repository Örneği
Worker içinde kullanmak için basit bir repository:
class SyncRepository @Inject constructor() {
suspend fun syncData() {
Log.d("SyncWorker","SyncRepository syncData working...")
}
}
Worker Implementasyonu
@HiltWorker
class SyncWorker @AssistedInject constructor(
@Assisted context: Context,
@Assisted parameters: WorkerParameters,
private val syncRepository: SyncRepository
) : CoroutineWorker(context, parameters) {
override suspend fun doWork(): Result {
return try {
Log.d("SyncWorker", "SyncWorker worked...")
syncRepository.syncData()
Result.success()
} catch (e: Exception) {
Log.d("SyncWorker", "SyncWorker did not work...$e")
Result.retry()
}
}
}
Açıklamalar
- @HiltWorker → Bu class’ın Hilt tarafından oluşturulacağını belirtir
- @AssistedInject → Bazı parametrelerin (Context, WorkerParameters) sistem tarafından verileceğini ifade eder
- SyncRepository → Hilt tarafından inject edilir
- CoroutineWorker -> CoroutineWorker kullanırız çünkü suspend fonksiyonları direkt kullanabiliriz. Blocking thread kullanmaz.
Gelişmiş Hata Yönetimi
override suspend fun doWork(): Result {
return try {
syncRepository.syncData()
Result.success()
} catch (e: IOException) {
Result.retry()
} catch (e: HttpException) {
if (e.code() >= 500) {
Result.retry()
} else {
Result.failure()
}
} catch (e: Exception) {
Result.failure()
}
}
- Network hatası → retry
- Server error → retry
- Client error → failure
Önemli Hata
SyncWorker sınıfına context, parameters ve syncRepository olmak üzere 3 adet parametre ekledik. Ancak CoroutineWorkers ile sadece context ve parameters alıyoruz. Bu tarz bir kullanımda aşağıdaki hata alıancaktr.
NoSuchMethodException: SyncWorker.<init>(Context, WorkerParameters)
Sebebi: WorkManager default olarak sadece bu iki parametreyi bekler. Bu hatanın çözümlenebilmesi için kendimize ait bir CustomWorkManager tanımlamamız gerekiyor.
CustomWorkerManager
class CustomWorkManager(
private val syncRepository: SyncRepository
) : WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): ListenableWorker? {
return SyncWorker(appContext, workerParameters, syncRepository)
}
}
Application Config
Oluşturdumuz SyncWorker sınıfında appContext ve workerParameters haricinde ekstra bir parametre olsun yada olmasın fark etmez, WorkManager çalışması için bu eklemenin @HiltAndroidApp annotation’ı eklenmiş Application sınıfınada eklenmesi gerekmektedir.
@HiltAndroidApp
class MyApplication : Application(), Configuration.Provider {
@Inject
lateinit var syncRepository: SyncRepository
override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setWorkerFactory(CustomWorkManager(syncRepository))
.build()
}
Eğerki SyncWorker sınıfımız ekstra bir parametre almıyorsa setWorkerFactory içerisine sadece workerFactory ekleriz. Eğerki ekstra bir parametre alıyor ise CustomWorkManager(syncRepository) ekleriz. Eğer SyncWorker bir parametre alıyorsa sınıf içerisinden HiltWorkerFactory’yi silmemiz gerekir.
- @HiltAndroidApp -> Hilt’in giriş noktasıdır. Uygulama ayağa kalkarken dependency graph oluşturulur ve tüm inject işlemleri buradan başlar.
- Configuration.Provider -> Configuration.Provider ile WorkManager config yapısını manuel olarak veririz.
- • HiltWorkerFactory -> @HiltWorker ile oluşturulan (Örnek:SyncWorker) worker’ları üretir.
Manifest Ayarı
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
Hilt Module
Hilt tarafında SyncRepository kullanmak için SyncRepository module içerisine eklenmeli.
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
@Singleton
fun provideSyncRepository(): SyncRepository {
return SyncRepository()
}
}
ViewModel içerisinden SyncScheduler çağırılır ve kullanıma başlanır.
@HiltViewModel
class MainViewModel @Inject constructor(
private val syncScheduler: SyncScheduler
): ViewModel() {
fun onSyncClicked() {
syncScheduler.scheduleOneTimeSync()
}
}
Sonuç
WorkManager:
- Uygulama kapalı olsa bile çalışır
- Network geldiğinde tetiklenir
- Retry mekanizması vardır
- Doğru kullanıldığında production için oldukça güvenlidir
Özellikle:
- Sync işlemleri
- Background veri gönderimi
- Kritik görevler
için vazgeçilmezdir.
메타데이터
- post_id
- 769ef4d10538
- slug
- workmanager-769ef4d10538
- url
- https://medium.com/@denizbas92/workmanager-769ef4d10538
- canonical_url
- https://medium.com/@denizbas92/workmanager-769ef4d10538
- author_url
- https://medium.com/@denizbas92
- status
- ok
- fetched_at
- 2026-06-24 04:09:36