Android Kotlin Hakkında Temel Bilgiler 09.2: WorkManager

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

Neler öğreneceksiniz?

  • Bir iş birimini temsil eden Worker oluşturma
  • İş yapılmasını istemek için WorkRequest oluş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 WorkManager simgesini 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 WorkRequest planlayı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.

  1. DevBytes uygulamasını henüz edinmediyseniz bu codelab için DevBytes başlangıç kodunu GitHub'daki DevBytesRepository projesinden indirin.
  2. Kodu açın ve projeyi Android Studio'da açın.
  3. 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.
  4. 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.

  1. Android Studio'da tüm paketleri genişletin.
  2. database paketini keşfedin. Paket, veritabanı öğelerini ve Room kullanılarak uygulanan yerel veritabanını içerir.
  3. repository paketini keşfedin. Paket, veri katmanını uygulamanın geri kalanından ayıran VideosRepository sınıfını içerir.
  4. 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.

  1. build.gradle (Module:app) dosyasını açın ve projeye WorkManager bağı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"
  1. 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. WorkRequest kullanarak, cihazın prize takılması veya kablosuz bağlantının kurulması gibi Constraints yardımıyla çalışan görevin nasıl ve ne zaman çalıştırılacağını yapılandırın. WorkRequest işlevini daha sonraki bir görevde uygulayacaksınız.
  • WorkManager
    Bu sınıf, WorkRequest dersinizin 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. WorkManager iş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.

  1. devbyteviewer paketi içinde work adlı yeni bir paket oluşturun.
  2. work paketinin içinde RefreshDataWorker adlı yeni bir Kotlin sınıfı oluşturun.
  3. RefreshDataWorker sınıfını CoroutineWorker sınıfından genişletin. context ve WorkerParameters öğelerini oluşturucu parametreleri olarak iletin.
class RefreshDataWorker(appContext: Context, params: WorkerParameters) :
       CoroutineWorker(appContext, params) {
}
  1. Soyut sınıf hatasını düzeltmek için doWork() yöntemini RefreshDataWorker sı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:

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.

  1. RefreshDataWorker sınıfında, doWork() içinde bir VideosDatabase nesnesi ve bir VideosRepository nesnesi oluşturup örnekleyin.
override suspend fun doWork(): Result {
   val database = getDatabase(applicationContext)
   val repository = VideosRepository(database)

   return Result.success()
}
  1. RefreshDataWorker sınıfında, doWork() içinde, return ifadesinin üzerinde, refreshVideos() yöntemini try bloğ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.

  1. Referans olarak kullanabileceğiniz RefreshDataWorker sı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:

  • OneTimeWorkRequest sınıfı, tek seferlik görevler içindir. (Tek seferlik bir görev yalnızca bir kez yapılır.)
  • PeriodicWorkRequest sı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.

  1. DevByteApplication sı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() {
}
  1. 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 RefreshDataWorker sınıfını iletin. 1 tekrarlama aralığını TimeUnit. zaman birimiyle iletinDAYS.
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.

  1. RefreshDataWorker sı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"
}
  1. DevByteApplication sınıfında, setupRecurringWork() yönteminin sonunda enqueueUniquePeriodicWork() yöntemini kullanarak işi planlayın. ExistingPeriodicWorkPolicy için KEEP enum'unu iletin. repeatingRequest öğesini PeriodicWorkRequest parametresi 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.

  1. DevByteApplication sınıfının başında bir CoroutineScope nesnesi oluşturun. Dispatchers.Default öğesini oluşturucu parametresi olarak iletin.
private val applicationScope = CoroutineScope(Dispatchers.Default)
  1. DevByteApplication sınıfında, eşzamanlı rutin başlatmak için delayedInit() adlı yeni bir yöntem ekleyin.
private fun delayedInit() {
   applicationScope.launch {
   }
}
  1. delayedInit() yönteminin içinde setupRecurringWork() yöntemini çağırın.
  2. Timber'ın ilk kullanıma hazırlama işlemini onCreate() yönteminden delayedInit() yöntemine taşıyın.
private fun delayedInit() {
   applicationScope.launch {
       Timber.plant(Timber.DebugTree())
       setupRecurringWork()
   }
}
  1. DevByteApplication sınıfında, onCreate() yönteminin sonunda delayedInit() yöntemine bir çağrı ekleyin.
override fun onCreate() {
   super.onCreate()
   delayedInit()
}
  1. Android Studio penceresinin alt kısmındaki Logcat bölmesini açın. RefreshDataWorker filtresi.
  2. 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.

  1. DevByteApplication sınıfında, setupRecurringWork() yönteminin içinde mevcut repeatingRequest tanımını yorum satırı haline getirin. 15 dakikalı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()
  1. Android Studio'da Logcat bölmesini açın ve RefreshDataWorker ile filtreleyin. Önceki günlükleri temizlemek için Clear logcat (Logcat'i temizle) simgesini tıklayın .
  2. 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.)

  1. DevByteApplication sınıfında, setupRecurringWork() başlangıcında Constraints türünde bir val tanı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.

  1. constraints nesnesine 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 UNMETERED enum'unu kullanın.
.setRequiredNetworkType(NetworkType.UNMETERED)
  1. 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.

  1. DevByteApplication sınıfında, setupRecurringWork() yöntemi içinde Constraints nesnesini düzenli iş isteği repeatingRequest olarak 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.

  1. Daha önce planlanmış görevleri iptal etmek için uygulamayı cihazdan veya emülatörden kaldırın.
  2. 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. work filtresi.
  3. 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.
  4. 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
  1. 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.

  1. DevByteApplication sı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)
  1. İş isteğini, yalnızca cihaz şarj olurken çalışacak şekilde güncelleyin. Kısıtlamayı build() yöntem çağrısından önce ekleyin ve setRequiresCharging() yöntemini kullanın.
.setRequiresCharging(true)
  1. İş isteğini, yalnızca cihaz boştayken çalışacak şekilde güncelleyin. Kısıtlamayı build() yöntem çağrısından önce ekleyin ve setRequiresDeviceIdle() 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ü M ve 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()
  1. 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)
   }
  1. 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.
  2. 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.
  3. 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.

  • WorkManager API, 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 WorkManager kullanın.
  • WorkManager kitaplığındaki ana sınıflar Worker, WorkRequest ve WorkManager'dır.
  • Worker sınıfı, bir iş birimini temsil eder. Arka plan görevini uygulamak için Worker sınıfını genişletin ve doWork() yöntemini geçersiz kılın.
  • WorkRequest sınıfı, bir iş biriminin gerçekleştirilmesi için yapılan isteği temsil eder. WorkRequest, WorkManager içinde planladığınız işlerle ilgili parametreleri belirtmek için kullanılan temel sınıftır.
  • WorkRequest sınıfının iki somut uygulaması vardır: tek seferlik görevler için OneTimeWorkRequest ve düzenli iş istekleri için PeriodicWorkRequest.
  • WorkRequest tanımlarken Worker'nin ne zaman çalışacağını belirten Constraints değ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.Builder belgelerinde listelenen ayarlama yöntemlerini kullanın. Örneğin, cihazın pili azaldığında WorkRequest uygulamasının çalışmaması gerektiğini belirtmek için setRequiresBatteryNotLow() set yöntemini kullanın.
  • WorkRequest tanımladıktan sonra görevi Android sistemine devredin. Bunu yapmak için görevi WorkManager enqueue yöntemlerinden birini kullanarak planlayın.
  • Worker öğesinin tam olarak ne zaman yürütüleceği, WorkRequest iç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:

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: 10.1 Stiller ve temalar

Bu kurstaki diğer codelab'lerin bağlantılarını Android Kotlin Hakkında Temel Bilgiler codelab'leri açılış sayfasında bulabilirsiniz.