Bu codelab, Android Kotlin Hakkında Temel Bilgiler kursunun bir parçasıdır. Bu kurstan en iyi şekilde yararlanmak için codelab'leri sırayla tamamlamanızı öneririz. Kursla ilgili tüm codelab'ler Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında listelenir.
Giriş
Gerçek hayattaki çoğu uygulamanın uzun süren arka plan görevleri gerçekleştirmesi gerekir. Örneğin, bir uygulama sunucuya dosya yükleyebilir, sunucudaki verileri senkronize edip Room veritabanına kaydedebilir, sunucuya günlük gönderebilir veya veriler üzerinde maliyetli işlemler gerçekleştirebilir. Bu tür işlemler, kullanıcı arayüzü iş parçacığının (ana iş parçacığı) dışında, arka planda gerçekleştirilmelidir. Arka plandaki görevler, cihazın sınırlı kaynaklarını (ör. RAM ve pil) tüketir. Bu durum doğru şekilde ele alınmazsa kullanıcı deneyimi olumsuz etkilenebilir.
Bu codelab'de, optimize ve verimli bir şekilde arka plan görevi planlamak için WorkManager'ı nasıl kullanacağınızı öğreneceksiniz. Android'de arka planda işleme için kullanılabilen diğer çözümler hakkında daha fazla bilgi edinmek için Arka planda işleme kılavuzu başlıklı makaleyi inceleyin.
Bilmeniz gerekenler
- ViewModel,- LiveDatave- RoomAndroid Mimari Bileşenleri'ni kullanma
- LiveDatasınıfında nasıl dönüşüm yapılır?
- Coroutine oluşturma ve başlatma
- Veri bağlamada bağlama bağdaştırıcıları nasıl kullanılır?
- Depo kalıbı kullanarak önbelleğe alınmış verileri yükleme
Neler öğreneceksiniz?
- Bir iş birimini temsil eden Workeroluşturma
- İş yapılmasını istemek için WorkRequestoluşturma
- Bir çalışanın nasıl ve ne zaman çalışması gerektiğini tanımlamak için WorkRequestöğesine kısıtlamalar ekleme
- Arka plan görevlerini planlamak için WorkManagersimgesini kullanma
Yapacaklarınız
- DevBytes video oynatma listesini ağdan önceden getirmek için arka plan görevini yürütecek bir çalışan oluşturun.
- Çalışanı periyodik olarak çalışacak şekilde planlayın.
- WorkRequestöğesine kısıtlamalar ekleyin.
- Günde bir kez çalıştırılan düzenli bir WorkRequestplanlayın.
Bu codelab'de, önceki bir codelab'de geliştirdiğiniz DevBytes uygulamasında çalışacaksınız. (Bu uygulamaya sahip değilseniz bu ders için başlangıç kodunu indirebilirsiniz.)
DevBytes uygulamasında, Google Android geliştirici ilişkileri ekibi tarafından oluşturulan kısa eğitimler olan DevBytes videolarının listesi gösterilir. Videolarda, Android geliştirmeye yönelik geliştirici özellikleri ve en iyi uygulamalar tanıtılıyor.
Videoları günde bir kez önceden getirerek uygulamadaki kullanıcı deneyimini iyileştirirsiniz. Bu sayede kullanıcı, uygulamayı açtığı anda yeni içeriklerle karşılaşır.

Bu görevde, başlangıç kodunu indirip incelersiniz.
1. adım: Başlangıç uygulamasını indirip çalıştırın
Önceki codelab'de oluşturduğunuz DevBytes uygulamasıyla (varsa) çalışmaya devam edebilirsiniz. Alternatif olarak, başlangıç uygulamasını indirebilirsiniz.
Bu görevde, başlangıç uygulamasını indirip çalıştıracak ve başlangıç kodunu inceleyeceksiniz.
- DevBytes uygulamasını henüz edinmediyseniz bu codelab için DevBytes başlangıç kodunu GitHub'daki DevBytesRepository projesinden indirin.
- Kodu açın ve projeyi Android Studio'da açın.
- Henüz bağlı değilse test cihazınızı veya emülatörünüzü internete bağlayın. Uygulamayı oluşturup çalıştırın. Uygulama, ağdan DevByte videolarının listesini getirip görüntüler.
- Uygulamada herhangi bir videoya dokunarak YouTube uygulamasında açın.
2. adım: Kodu keşfedin
Başlangıç uygulaması, önceki codelab'de tanıtılan çok sayıda kodla birlikte gelir. Bu codelab'in başlangıç kodunda ağ, kullanıcı arayüzü, çevrimdışı önbellek ve depo modülleri bulunur. WorkManager kullanarak arka plan görevini planlamaya odaklanabilirsiniz. 
- Android Studio'da tüm paketleri genişletin.
- databasepaketini keşfedin. Paket, veritabanı öğelerini ve- Roomkullanılarak uygulanan yerel veritabanını içerir.
- repositorypaketini keşfedin. Paket, veri katmanını uygulamanın geri kalanından ayıran- VideosRepositorysınıfını içerir.
- Başlangıç kodunun geri kalanını kendi başınıza ve önceki codelab'in yardımıyla inceleyin.
WorkManager, Android Mimari Bileşenleri'nden biri ve Android Jetpack'in bir parçasıdır. WorkManager, ertelenebilir ve yürütülmesi garanti edilmesi gereken arka plan işleri içindir:
- Ertelenebilir, işin hemen çalıştırılması gerekmediği anlamına gelir. Örneğin, sunucuya analiz verileri gönderme veya veritabanını arka planda senkronize etme gibi işlemler ertelenebilir.
- Garantili yürütme, uygulama çıksa veya cihaz yeniden başlatılsa bile görevin çalışacağı anlamına gelir.

WorkManager arka planda çalışırken uyumluluk sorunlarını ve pil ile sistem sağlığıyla ilgili en iyi uygulamaları ele alır. WorkManager, API düzeyi 14'e kadar geriye dönük uyumluluk sunar. WorkManager, cihazın API düzeyine bağlı olarak arka plan görevini planlamak için uygun bir yöntem seçer. JobScheduler (API 23 ve sonraki sürümlerde) veya AlarmManager ile BroadcastReceiver kombinasyonu kullanabilir.
WorkManager, arka plan görevinin ne zaman çalışacağına dair ölçütler belirlemenize de olanak tanır. Örneğin, görevin yalnızca pil durumu, ağ durumu veya şarj durumu belirli ölçütleri karşıladığında çalışmasını isteyebilirsiniz. Kısıtlamaları nasıl ayarlayacağınızı bu codelab'in ilerleyen bölümlerinde öğreneceksiniz.
Bu codelab'de, DevBytes video oynatma listesini ağdan günde bir kez önceden getirmek için bir görev planlayacaksınız. Bu görevi planlamak için WorkManager kitaplığını kullanırsınız.
- build.gradle (Module:app)dosyasını açın ve projeye- WorkManagerbağımlılığını ekleyin.
 Kitaplığın en son sürümünü kullanıyorsanız çözüm uygulaması beklendiği gibi derlenmelidir. Çözülmezse sorunu gidermeyi deneyin veya aşağıda gösterilen kitaplık sürümüne geri dönün.
// WorkManager dependency
def work_version = "1.0.1"
implementation "android.arch.work:work-runtime-ktx:$work_version"- Projenizi senkronize edin ve derleme hatası olmadığından emin olun.
Projeye kod eklemeden önce WorkManager kitaplığındaki aşağıdaki sınıflar hakkında bilgi edinin:
- Worker
 Bu sınıfta, arka planda çalıştırılacak gerçek işi (görevi) tanımlarsınız. Bu sınıfı genişletir ve- doWork()yöntemini geçersiz kılarsınız.- doWork()yöntemi, verileri sunucuyla senkronize etme veya resimleri işleme gibi arka planda gerçekleştirilecek kodları yerleştirdiğiniz yerdir. Bu görevde- Workeröğesini uygulayacaksınız.
- WorkRequest
 Bu sınıf, çalışanın arka planda çalıştırılması isteğini temsil eder.- WorkRequestkullanarak, cihazın prize takılması veya kablosuz bağlantının kurulması gibi- Constraintsyardımıyla çalışan görevin nasıl ve ne zaman çalıştırılacağını yapılandırın.- WorkRequestişlevini daha sonraki bir görevde uygulayacaksınız.
- WorkManager
 Bu sınıf,- WorkRequestdersinizin programını oluşturur ve dersi yürütür.- WorkManager, iş isteklerini, belirttiğiniz kısıtlamalara uyarak sistem kaynaklarındaki yükü dağıtacak şekilde planlar.- WorkManagerişlevini daha sonraki bir görevde uygulayacaksınız.
1. adım: Çalışan oluşturun
Bu görevde, DevBytes video oynatma listesini arka planda önceden getirmek için Worker ekliyorsunuz.
- devbyteviewerpaketi içinde- workadlı yeni bir paket oluşturun.
- workpaketinin içinde- RefreshDataWorkeradlı yeni bir Kotlin sınıfı oluşturun.
- RefreshDataWorkersınıfını- CoroutineWorkersınıfından genişletin.- contextve- WorkerParametersöğelerini oluşturucu parametreleri olarak iletin.
class RefreshDataWorker(appContext: Context, params: WorkerParameters) :
       CoroutineWorker(appContext, params) {
}- Soyut sınıf hatasını düzeltmek için doWork()yönteminiRefreshDataWorkersınıfında geçersiz kılın.
override suspend fun doWork(): Result {
  return Result.success()
}Askıya alma işlevi, duraklatılabilen ve daha sonra devam ettirilebilen bir işlevdir. Askıya alma işlevi, uzun süren bir işlemi yürütebilir ve ana ileti dizisini engellemeden işlemin tamamlanmasını bekleyebilir.
2. adım: doWork() işlevini uygulama
Worker sınıfındaki doWork() yöntemi, arka plan iş parçacığında çağrılır. Yöntem, işi eşzamanlı olarak gerçekleştirir ve bir ListenableWorker.Result nesnesi döndürmelidir. Android sistemi, Worker öğesine yürütmesini tamamlaması ve ListenableWorker.Result nesnesi döndürmesi için en fazla 10 dakika süre tanır. Bu süre dolduktan sonra sistem, Worker işlemini zorla durdurur.
Bir ListenableWorker.Result nesnesi oluşturmak için aşağıdaki statik yöntemlerden birini çağırarak arka planda yapılan çalışmanın tamamlanma durumunu belirtin:
- Result.success(): Çalışma başarıyla tamamlandı.
- Result.failure(): İş, kalıcı bir hatayla tamamlandı.
- Result.retry(): Çalışmada geçici bir hata oluştu ve yeniden denenmesi gerekiyor.
Bu görevde, DevBytes video oynatma listesini ağdan getirmek için doWork() yöntemini uygulayacaksınız. Verileri ağdan almak için VideosRepository sınıfındaki mevcut yöntemleri yeniden kullanabilirsiniz.
- RefreshDataWorkersınıfında,- doWork()içinde bir- VideosDatabasenesnesi ve bir- VideosRepositorynesnesi oluşturup örnekleyin.
override suspend fun doWork(): Result {
   val database = getDatabase(applicationContext)
   val repository = VideosRepository(database)
   return Result.success()
}- RefreshDataWorkersınıfında,- doWork()içinde,- returnifadesinin üzerinde,- refreshVideos()yöntemini- trybloğunda çağırın. Çalışanın ne zaman çalıştırıldığını izlemek için günlük ekleyin.
try {
   repository.refreshVideos( )
   Timber.d("Work request for sync is run")
   } catch (e: HttpException) {
   return Result.retry()
}"Çözümlenmemiş referans" hatasını düzeltmek için retrofit2.HttpException dosyasını içe aktarın.
- Referans olarak kullanabileceğiniz RefreshDataWorkersınıfının tamamını aşağıda bulabilirsiniz:
class RefreshDataWorker(appContext: Context, params: WorkerParameters) :
       CoroutineWorker(appContext, params) {
   override suspend fun doWork(): Result {
       val database = getDatabase(applicationContext)
       val repository = VideosRepository(database)
       try {
           repository.refreshVideos()
       } catch (e: HttpException) {
           return Result.retry()
       }
       return Result.success()
   }
}Worker bir iş birimini tanımlar ve WorkRequest işin nasıl ve ne zaman yürütülmesi gerektiğini tanımlar. WorkRequest sınıfının iki somut uygulaması vardır: 
- OneTimeWorkRequestsınıfı, tek seferlik görevler içindir. (Tek seferlik bir görev yalnızca bir kez yapılır.)
- PeriodicWorkRequestsınıfı, periyodik çalışmalar ve belirli aralıklarla tekrarlanan çalışmalar için kullanılır.
Görevler tek seferlik veya düzenli olabilir. Bu nedenle, sınıfı buna göre seçin. Tekrarlayan işleri planlama hakkında daha fazla bilgi için tekrarlayan işler dokümanlarına bakın.
Bu görevde, önceki görevde oluşturduğunuz çalışanı çalıştırmak için bir WorkRequest tanımlayıp planlayacaksınız. 
1. adım: Tekrarlanan işleri ayarlayın
Bir Android uygulamasında Application sınıfı, etkinlikler ve hizmetler gibi diğer tüm bileşenleri içeren temel sınıftır. Uygulamanız veya paketiniz için süreç oluşturulduğunda Application sınıfı (veya Application sınıfının herhangi bir alt sınıfı), diğer tüm sınıflardan önce başlatılır.
Bu örnek uygulamada, DevByteApplication sınıfı, Application sınıfının bir alt sınıfıdır. DevByteApplication sınıfı, WorkManager planlamak için iyi bir yerdir.
- DevByteApplicationsınıfında, yinelenen arka plan görevini ayarlamak için- setupRecurringWork()adlı bir yöntem oluşturun.
/**
* Setup WorkManager background job to 'fetch' new network data daily.
*/
private fun setupRecurringWork() {
}- setupRecurringWork()yöntemi içinde,- PeriodicWorkRequestBuilder()yöntemini kullanarak günde bir kez çalışacak periyodik bir iş isteği oluşturun ve başlatın. Önceki görevde oluşturduğunuz- RefreshDataWorkersınıfını iletin.- 1tekrarlama aralığını- TimeUnit.zaman birimiyle iletin- DAYS.
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
       .build()Hatayı düzeltmek için java.util.concurrent.TimeUnit öğesini içe aktarın.
2. adım: WorkManager ile WorkRequest planlayın
WorkRequest tanımladıktan sonra enqueueUniquePeriodicWork() yöntemini kullanarak WorkManager ile planlayabilirsiniz. Bu yöntem, kuyruğa benzersiz bir şekilde adlandırılmış PeriodicWorkRequest eklemenize olanak tanır. Belirli bir ada sahip yalnızca bir PeriodicWorkRequest aynı anda etkin olabilir.
Örneğin, yalnızca bir senkronizasyon işleminin etkin olmasını isteyebilirsiniz. Bekleyen bir senkronizasyon işlemi varsa bu işlemin çalışmasına izin verebilir veya ExistingPeriodicWorkPolicy kullanarak yeni çalışmanızla değiştirebilirsiniz.
WorkRequest planlama yöntemleri hakkında daha fazla bilgi edinmek için WorkManager belgelerine bakın.
- RefreshDataWorkersınıfında, sınıfın başında bir yardımcı nesne ekleyin. Bu çalışanı benzersiz şekilde tanımlamak için bir iş adı tanımlayın.
companion object {
   const val WORK_NAME = "com.example.android.devbyteviewer.work.RefreshDataWorker"
}- DevByteApplicationsınıfında,- setupRecurringWork()yönteminin sonunda- enqueueUniquePeriodicWork()yöntemini kullanarak işi planlayın. ExistingPeriodicWorkPolicy için- KEEPenum'unu iletin.- repeatingRequestöğesini- PeriodicWorkRequestparametresi olarak iletin.
WorkManager.getInstance().enqueueUniquePeriodicWork(
       RefreshDataWorker.WORK_NAME,
       ExistingPeriodicWorkPolicy.KEEP,
       repeatingRequest)Aynı ada sahip bekleyen (tamamlanmamış) bir çalışma varsa ExistingPeriodicWorkPolicy.KEEP parametresi, WorkManager'in önceki periyodik çalışmayı tutmasını ve yeni çalışma isteğini atmasını sağlar.
- DevByteApplicationsınıfının başında bir- CoroutineScopenesnesi oluşturun.- Dispatchers.Defaultöğesini oluşturucu parametresi olarak iletin.
private val applicationScope = CoroutineScope(Dispatchers.Default)- DevByteApplicationsınıfında, eşzamanlı rutin başlatmak için- delayedInit()adlı yeni bir yöntem ekleyin.
private fun delayedInit() {
   applicationScope.launch {
   }
}- delayedInit()yönteminin içinde- setupRecurringWork()yöntemini çağırın.
- Timber'ın ilk kullanıma hazırlama işlemini onCreate()yöntemindendelayedInit()yöntemine taşıyın.
private fun delayedInit() {
   applicationScope.launch {
       Timber.plant(Timber.DebugTree())
       setupRecurringWork()
   }
}- DevByteApplicationsınıfında,- onCreate()yönteminin sonunda- delayedInit()yöntemine bir çağrı ekleyin.
override fun onCreate() {
   super.onCreate()
   delayedInit()
}- Android Studio penceresinin alt kısmındaki Logcat bölmesini açın. RefreshDataWorkerfiltresi.
- Uygulamayı çalıştırın. WorkManager, yinelenen işlerinizi hemen planlar.
 Logcat bölmesinde, iş isteğinin planlandığını ve başarıyla çalıştığını gösteren günlük ifadelerine dikkat edin.
D/RefreshDataWorker: Work request for sync is run I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]
WM-WorkerWrapper günlüğü, WorkManager kitaplığından gösterildiğinden bu günlük mesajını değiştiremezsiniz.
3. adım: (İsteğe bağlı) WorkRequest'i minimum aralık için planlayın
Bu adımda, zaman aralığını 1 günden 15 dakikaya düşürürsünüz. Bunu, periyodik bir çalışma isteğinin günlüklerini işlem sırasında görebilmek için yaparsınız.
- DevByteApplicationsınıfında,- setupRecurringWork()yönteminin içinde mevcut- repeatingRequesttanımını yorum satırı haline getirin.- 15dakikalık periyodik tekrar aralığına sahip yeni bir iş isteği ekleyin.
// val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
//        .build()
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(15, TimeUnit.MINUTES)
       .build()- Android Studio'da Logcat bölmesini açın ve RefreshDataWorkerile filtreleyin. Önceki günlükleri temizlemek için Clear logcat (Logcat'i temizle) simgesini tıklayın . tıklayın .
- Uygulamayı çalıştırın. WorkManager, yinelenen işinizi hemen planlar. Logcat bölmesinde günlükleri inceleyin. İş isteği 15 dakikada bir kez çalıştırılır. Başka bir iş isteği günlükleri grubunu görmek için 15 dakika bekleyin. Uygulamayı çalışır durumda bırakabilir veya kapatabilirsiniz. Work Manager yine de çalışmaya devam eder.
 Aralığın bazen 15 dakikadan kısa, bazen de 15 dakikadan uzun olduğunu unutmayın. (Tam zamanlama, işletim sisteminin pil optimizasyonlarına bağlıdır.)
12:44:40 D/RefreshDataWorker: Work request for sync is run 12:44:40 I/WM-WorkerWrapper: Worker result SUCCESS for Work 12:59:24 D/RefreshDataWorker: Work request for sync is run 12:59:24 I/WM-WorkerWrapper: Worker result SUCCESS for Work 13:15:03 D/RefreshDataWorker: Work request for sync is run 13:15:03 I/WM-WorkerWrapper: Worker result SUCCESS for Work 13:29:22 D/RefreshDataWorker: Work request for sync is run 13:29:22 I/WM-WorkerWrapper: Worker result SUCCESS for Work 13:44:26 D/RefreshDataWorker: Work request for sync is run 13:44:26 I/WM-WorkerWrapper: Worker result SUCCESS for Work
 Tebrikler! Bir çalışan oluşturdunuz ve WorkManager ile iş isteğini planladınız. Ancak bir sorun var: Herhangi bir kısıtlama belirtmediniz. WorkManager, cihazın pili az olsa, uyku modunda olsa veya ağ bağlantısı olmasa bile çalışmayı günde bir kez planlar. Bu durum, cihazın pilini ve performansını etkiler ve kötü bir kullanıcı deneyimine yol açabilir.
Bir sonraki görevde, kısıtlamalar ekleyerek bu sorunu ele alacaksınız.
Önceki görevde, iş isteği planlamak için WorkManager simgesini kullandınız. Bu görevde, çalışmanın ne zaman yürütüleceğine dair ölçütler ekleyeceksiniz.
WorkRequest tanımlarken Worker öğesinin ne zaman çalışması gerektiğiyle ilgili kısıtlamalar belirtebilirsiniz. Örneğin, işin yalnızca cihaz boşta olduğunda veya yalnızca cihaz prize takılıyken ve kablosuz ağa bağlıyken çalışmasını belirtebilirsiniz. Ayrıca, işi yeniden denemek için bir geri çekilme politikası da belirtebilirsiniz. Desteklenen kısıtlamalar, Constraints.Builder içindeki yöntemlerdir. Daha fazla bilgi edinmek için İş İsteklerinizi Tanımlama başlıklı makaleyi inceleyin.
1. adım: Kısıtlamalar nesnesi ekleyin ve bir kısıtlama ayarlayın
Bu adımda bir Constraints nesnesi oluşturup nesne üzerinde bir kısıtlama (ağ türü kısıtlaması) ayarlarsınız. (Günlükleri tek bir kısıtlamayla fark etmek daha kolaydır. Daha sonraki bir adımda diğer kısıtlamaları eklersiniz.)
- DevByteApplicationsınıfında,- setupRecurringWork()başlangıcında- Constraintstüründe bir- valtanımlayın.- Constraints.Builder()yöntemini kullanın.
val constraints = Constraints.Builder()Hatayı düzeltmek için androidx.work.Constraints öğesini içe aktarın.
- constraintsnesnesine ağ türünde bir kısıtlama eklemek için- setRequiredNetworkType()yöntemini kullanın. İş isteğinin yalnızca cihaz ölçülmemiş bir ağa bağlıyken çalışması için- UNMETEREDenum'unu kullanın.
.setRequiredNetworkType(NetworkType.UNMETERED)- Oluşturucudan kısıtlamalar oluşturmak için build()yöntemini kullanın.
val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .build()Şimdi yeni oluşturulan Constraints nesnesini iş isteğine ayarlamanız gerekiyor.
- DevByteApplicationsınıfında,- setupRecurringWork()yöntemi içinde- Constraintsnesnesini düzenli iş isteği- repeatingRequestolarak ayarlayın. Kısıtlamaları ayarlamak için- build()yöntem çağrısının üzerine- setConstraints()yöntemini ekleyin.
       val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(15, TimeUnit.MINUTES)
               .setConstraints(constraints)
               .build()2. adım: Uygulamayı çalıştırın ve günlükleri inceleyin
Bu adımda uygulamayı çalıştırır ve kısıtlanmış iş isteğinin belirli aralıklarla arka planda çalıştırıldığını görürsünüz.
- Daha önce planlanmış görevleri iptal etmek için uygulamayı cihazdan veya emülatörden kaldırın.
- Android Studio'da Logcat bölmesini açın. Logcat bölmesinde, soldaki Clear logcat (Logcat'i temizle) simgesini tıklayarak önceki günlükleri temizleyin. tıklayarak önceki günlükleri temizleyin.workfiltresi.
- Kısıtlamaların nasıl çalıştığını görmek için cihazda veya emülatörde kablosuz bağlantıyı kapatın. Mevcut kod yalnızca bir kısıtlama belirleyerek isteğin yalnızca ölçülmemiş bir ağda çalıştırılması gerektiğini belirtir. Kablosuz bağlantı kapalı olduğundan cihaz, ücretli veya ücretsiz ağa bağlı değil. Bu nedenle bu kısıtlama karşılanmayacaktır.
- Uygulamayı çalıştırın ve Logcat bölmesine dikkat edin. WorkManager, arka plan görevini hemen planlar. Ağ kısıtlaması karşılanmadığı için görev çalıştırılmıyor.
11:31:44 D/DevByteApplication: Periodic Work request for sync is scheduled
- Cihazda veya emülatörde kablosuz bağlantıyı açın ve Logcat bölmesini izleyin. Artık planlanan arka plan görevi, ağ kısıtlaması karşılandığı sürece yaklaşık 15 dakikada bir çalıştırılıyor.
11:31:44 D/DevByteApplication: Periodic Work request for sync is scheduled 11:31:47 D/RefreshDataWorker: Work request for sync is run 11:31:47 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 11:46:45 D/RefreshDataWorker: Work request for sync is run 11:46:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 12:03:05 D/RefreshDataWorker: Work request for sync is run 12:03:05 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 12:16:45 D/RefreshDataWorker: Work request for sync is run 12:16:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 12:31:45 D/RefreshDataWorker: Work request for sync is run 12:31:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 12:47:05 D/RefreshDataWorker: Work request for sync is run 12:47:05 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...] 13:01:45 D/RefreshDataWorker: Work request for sync is run 13:01:45 I/WM-WorkerWrapper: Worker result SUCCESS for Work [...]
3. adım: Daha fazla kısıtlama ekleyin
Bu adımda, PeriodicWorkRequest alanına aşağıdaki kısıtlamaları eklersiniz: 
- Pil seviyesi düşük değil.
- Cihaz şarjı.
- Cihaz boşta: Yalnızca API düzeyi 23 (Android M) ve sonraki sürümlerde kullanılabilir.
DevByteApplication sınıfında aşağıdakileri uygulayın.
- DevByteApplicationsınıfındaki- setupRecurringWork()yönteminde, iş isteğinin yalnızca pil seviyesi düşük olmadığında çalışması gerektiğini belirtin. Kısıtlamayı- build()yöntem çağrısından önce ekleyin ve- setRequiresBatteryNotLow()yöntemini kullanın.
.setRequiresBatteryNotLow(true)- İş isteğini, yalnızca cihaz şarj olurken çalışacak şekilde güncelleyin. Kısıtlamayı build()yöntem çağrısından önce ekleyin vesetRequiresCharging()yöntemini kullanın.
.setRequiresCharging(true)- İş isteğini, yalnızca cihaz boştayken çalışacak şekilde güncelleyin. Kısıtlamayı build()yöntem çağrısından önce ekleyin vesetRequiresDeviceIdle()yöntemini kullanın. Bu kısıtlama, iş isteğini yalnızca kullanıcı cihazı etkin olarak kullanmadığında çalıştırır. Bu özellik yalnızca Android 6.0 (Marshmallow) ve sonraki sürümlerde kullanılabilir. Bu nedenle, SDK sürümüMve sonraki sürümler için bir koşul ekleyin.
.apply {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       setRequiresDeviceIdle(true)
   }
}constraints nesnesinin tam tanımı aşağıda verilmiştir.
val constraints = Constraints.Builder()
       .setRequiredNetworkType(NetworkType.UNMETERED)
       .setRequiresBatteryNotLow(true)
       .setRequiresCharging(true)
       .apply {
           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
               setRequiresDeviceIdle(true)
           }
       }
       .build()- setupRecurringWork()yönteminin içinde, istek aralığını tekrar günde bir kez olarak değiştirin.
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
       .setConstraints(constraints)
       .build()Burada, periyodik iş isteğinin ne zaman planlandığını takip edebilmeniz için bir günlükle birlikte setupRecurringWork() yönteminin tam uygulaması yer almaktadır. 
private fun setupRecurringWork() {
       val constraints = Constraints.Builder()
               .setRequiredNetworkType(NetworkType.UNMETERED)
               .setRequiresBatteryNotLow(true)
               .setRequiresCharging(true)
               .apply {
                   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                       setRequiresDeviceIdle(true)
                   }
               }
               .build()
       val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
               .setConstraints(constraints)
               .build()
       
       Timber.d("Periodic Work request for sync is scheduled")
       WorkManager.getInstance().enqueueUniquePeriodicWork(
               RefreshDataWorker.WORK_NAME,
               ExistingPeriodicWorkPolicy.KEEP,
               repeatingRequest)
   }- Daha önce planlanmış iş isteğini kaldırmak için DevBytes uygulamasını cihazınızdan veya emülatörünüzden kaldırın.
- Uygulamayı çalıştırdığınızda WorkManager, iş isteğini hemen planlar. Çalışma isteği, tüm kısıtlamalar karşılandığında günde bir kez çalıştırılır.
- Bu çalışma isteği, uygulama çalışmıyor olsa bile yüklü olduğu sürece arka planda çalışır. Bu nedenle, uygulamayı telefondan kaldırmanız gerekir.
Mükemmel! DevBytes uygulamasında videoların günlük önceden getirilmesi için pil dostu bir iş isteği uygulayıp planladınız. WorkManager, işi planlayıp çalıştırarak sistem kaynaklarını optimize eder. Kullanıcılarınız ve pilleri çok mutlu olacak.
Android Studio projesi: DevBytesWorkManager.
- WorkManagerAPI, güvenilir bir şekilde çalıştırılması gereken ertelenebilir ve eşzamansız görevleri planlamayı kolaylaştırır.
- Gerçek hayattaki çoğu uygulamanın uzun süren arka plan görevleri gerçekleştirmesi gerekir. Arka plan görevini optimize edilmiş ve verimli bir şekilde planlamak için WorkManagerkullanın.
- WorkManagerkitaplığındaki ana sınıflar- Worker,- WorkRequestve- WorkManager'dır.
- Workersınıfı, bir iş birimini temsil eder. Arka plan görevini uygulamak için- Workersınıfını genişletin ve- doWork()yöntemini geçersiz kılın.
- WorkRequestsınıfı, bir iş biriminin gerçekleştirilmesi için yapılan isteği temsil eder.- WorkRequest,- WorkManageriçinde planladığınız işlerle ilgili parametreleri belirtmek için kullanılan temel sınıftır.
- WorkRequestsınıfının iki somut uygulaması vardır: tek seferlik görevler için- OneTimeWorkRequestve düzenli iş istekleri için- PeriodicWorkRequest.
- WorkRequesttanımlarken- Worker'nin ne zaman çalışacağını belirten- Constraintsdeğerini belirtebilirsiniz. Kısıtlamalar arasında cihazın prize takılı olup olmadığı, boşta olup olmadığı veya kablosuz ağa bağlı olup olmadığı gibi durumlar yer alır.
- WorkRequestöğesine kısıtlamalar eklemek için- Constraints.Builderbelgelerinde listelenen ayarlama yöntemlerini kullanın. Örneğin, cihazın pili azaldığında- WorkRequestuygulamasının çalışmaması gerektiğini belirtmek için- setRequiresBatteryNotLow()set yöntemini kullanın.
- WorkRequesttanımladıktan sonra görevi Android sistemine devredin. Bunu yapmak için görevi- WorkManager- enqueueyöntemlerinden birini kullanarak planlayın.
- Workeröğesinin tam olarak ne zaman yürütüleceği,- WorkRequestiçinde kullanılan kısıtlamalara ve sistem optimizasyonlarına bağlıdır.- WorkManager, bu kısıtlamalar göz önünde bulundurulduğunda mümkün olan en iyi davranışı sunmak için tasarlanmıştır.
Udacity kursu:
Android geliştirici belgeleri:
- İş İsteklerinizi Tanımlama
- WorkManager
- WorkManager'ı kullanmaya başlama
- Yinelenen çalışmalar
- Arka planda işleme kılavuzu
Diğer:
Bu bölümde, bir eğitmenin yönettiği kurs kapsamında bu codelab'i tamamlayan öğrenciler için olası ödevler listelenmektedir. Eğitmen, aşağıdakileri yapmalıdır:
- Gerekirse ödev atayın.
- Öğrencilere ev ödevi ödevlerini nasıl göndereceklerini bildirin.
- Ödevlere not verin.
Eğitmenler bu önerileri istedikleri kadar kullanabilir ve uygun olduğunu düşündükleri diğer ödevleri verebilirler.
Bu codelab'i kendi başınıza tamamlıyorsanız bilginizi test etmek için bu ödevleri kullanabilirsiniz.
1. Soru
WorkRequest sınıfının somut uygulamaları nelerdir? 
▢ OneTimeWorkPeriodicRequest
▢ OneTimeWorkRequest ve PeriodicWorkRequest
▢ OneTimeWorkRequest ve RecurringWorkRequest
▢ OneTimeOffWorkRequest ve RecurringWorkRequest
2. Soru
WorkManager, API 23 ve sonraki sürümlerde arka plan görevini planlamak için aşağıdaki sınıflardan hangisini kullanır? 
▢ Yalnızca JobScheduler
▢ BroadcastReceiver ve AlarmManager
▢ AlarmManager ve JobScheduler
▢ Scheduler ve BroadcastReceiver
3. Soru
WorkRequest öğesine kısıtlamalar eklemek için hangi API'yi kullanıyorsunuz? 
▢ setConstraints()
▢ addConstraints()
▢ setConstraint()
▢ addConstraintsToWorkRequest()
Bir sonraki derse geçin: 
Bu kurstaki diğer codelab'lerin bağlantılarını Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında bulabilirsiniz.