Android Kotlin Temelleri 09.2: WorkManager

Bu codelab, Android Kotlin Temelleri kursuna dahildir. Codelab'ler üzerinden sırayla çalışıyorsanız bu kurstan en iyi şekilde yararlanabilirsiniz. Tüm kurs codelab'leri Android Kotlin Fundamentals codelabs açılış sayfasında listelenmektedir.

Giriş

Gerçek dünyadaki çoğu uygulamanın uzun süreli arka planda görevleri yerine getirmesi gerekir. Örneğin, bir uygulama bir sunucuya dosya yükleyebilir, bir sunucudaki verileri senkronize edebilir ve bir Room veritabanına kaydedebilir, bir sunucuya günlük gönderebilir veya veriler üzerinde pahalı işlemler gerçekleştirebilir. Bu tür işlemler arka planda, kullanıcı arayüzü iş parçacığının (ana iş parçacığı) dışında gerçekleştirilmelidir. Arka plan görevleri, cihazın RAM ve pil gibi sınırlı kaynaklarını tüketir. Bu, doğru şekilde işlenmediği takdirde kullanıcı için kötü bir deneyime neden olabilir.

Bu codelab'de, arka plan görevini optimize edilmiş ve verimli bir şekilde planlamak için WorkManager'i nasıl kullanacağınızı öğrenebilirsiniz. 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 rehberi'ne bakın.

Bilmeniz gerekenler

  • ViewModel, LiveData ve Room Android Mimari Bileşenleri nasıl kullanılır?
  • LiveData sınıfında dönüşümler nasıl yapılır?
  • Donatı oluşturma ve kullanıma sunma.
  • Veri bağlamada bağlama adaptörleri nasıl kullanılır?
  • Depo kalıbı kullanarak önbelleğe alınmış veri yükleme.

Neler öğreneceksiniz?

  • Bir çalışma birimini temsil eden Worker nasıl oluşturulur?
  • Bir işin gerçekleştirilmesini istemek için nasıl WorkRequest oluşturacağınızı belirtir.
  • 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örevleri planlamak için WorkManager nasıl kullanılır?

Yapacaklarınız

  • DevBytes video oynatma listesini ağdan önceden getirmek için arka plan görevi çalıştırmak üzere bir çalışan oluşturun.
  • Çalışanı düzenli olarak çalışacak şekilde programlayın.
  • WorkRequest öğesine kısıtlamalar ekleyin.
  • Günde bir kez yürütülen periyodik bir WorkRequest programlayın.

Bu codelab'de, önceki bir codelab'de geliştirdiğiniz DevBytes uygulaması üzerinde çalışıyorsunuz. (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 yapılan kısa eğitimler olan DevByte videolarının listesi görüntülenir. Videolarda Android geliştirme için geliştirici özellikleri ve en iyi uygulamalar bulunuyor.

Videoları günde bir kez önceden getirerek uygulamadaki kullanıcı deneyimini iyileştirebilirsiniz. Bu, kullanıcının uygulamayı açar açmaz yeni içerik almasını sağlar.

Bu görevde başlangıç kodunu indirip incelersiniz.

1. Adım: Başlangıç uygulamasını indirin ve çalıştırın

Önceki codelab'de oluşturduğunuz DevBytes uygulaması üzerinden çalışmaya devam edebilirsiniz. Alternatif olarak başlangıç uygulamasını indirebilirsiniz.

Bu görevde başlangıç uygulamasını indirip çalıştırın ve başlangıç kodunu inceleyin.

  1. Henüz DevBytes uygulamanız yoksa bu codelab için GitHub'daki DevBytesRepository projesinden DevBytes başlangıç kodunu indirin.
  2. Kodu arşivden çıkarıp 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ğdaki DevByte video listesini getirir ve görüntüler.
  4. Uygulamada herhangi bir videoya dokunarak videoyu YouTube uygulamasında açın.

2. Adım: Kodu keşfedin

Başlangıç uygulaması, önceki codelab'de kullanıma sunulan çok sayıda kodla birlikte gelir. Bu codelab'in başlangıç kodu; ağ iletişimi, kullanıcı arayüzü, çevrimdışı önbellek ve depo modüllerine sahiptir. WorkManager aracını kullanarak arka plan görevini planlamaya odaklanabilirsiniz.

  1. Android Studio'da tüm paketleri genişletin.
  2. database paketini keşfedin. Paket, Room kullanılarak uygulanan veritabanı varlıklarını ve yerel veritabanını içerir.
  3. repository paketini keşfedin. Paket, uygulamanın geri kalanından veri katmanını soyutlayan VideosRepository sınıfını içerir.
  4. Başlangıç kodundaki diğer özellikleri kendi başınıza ve önceki codelab'in yardımıyla keşfedin.

WorkManager, Android Mimari Bileşenleri'nden biridir ve Android Jetpack'in bir parçasıdır. WorkManager, ertelenebilir ve garantili yürütme gerektiren arka plan çalışmaları içindir:

  • Ertelenebilir, çalışmanın hemen çalıştırılmasına gerek olmadığı anlamına gelir. Örneğin, analitik verileri sunucuya göndermek veya veritabanını arka planda senkronize etmek ertelenebilir.
  • Garantili yürütme, uygulama çıksa veya cihaz yeniden başlatılsa bile görevin çalışacağı anlamına gelir.

WorkManager arka plandaki çalışmaları çalıştırırken uyumluluk sorunları ile pil ve sistem sağlığı için en iyi uygulamalarla ilgilenir. WorkManager, API 14 düzeyine kadar uyumluluk sunar. WorkManager, cihaz API düzeyine bağlı olarak arka plan görevi programlamak için uygun bir yöntem seçer. JobScheduler (API 23 ve üstü) veya AlarmManager ile BroadcastReceiver'in bir kombinasyonunu kullanabilir.

WorkManager, arka plan görevinin ne zaman çalıştırılacağıyla ilgili ölçütler de ayarlamanıza 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. Bu codelab'in ilerleyen bölümlerinde kısıtlamaları nasıl ayarlayacağınızı öğreneceksiniz.

Bu codelab'de, DevBytes video oynatma listesini günde bir kez önceden getirmek için bir görev planlıyorsunuz. Bu görevi planlamak için WorkManager kitaplığını kullanın.

  1. build.gradle (Module:app) dosyasını açın ve projeye WorkManager bağımlılığını ekleyin.

    Kitaplıkın en son sürümünü kullanıyorsanız çözüm uygulaması beklendiği gibi derlenmelidir. Sorun çözülmediyse sorunu çözmeyi 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ıf, arka planda çalıştırılacak asıl işi (görevi) tanımladığınız yerdir. Bu sınıfı genişletir ve doWork() yöntemini geçersiz kılarsınız. doWork() yöntemi, verileri sunucuyla senkronize etmek veya resimleri işlemek gibi arka planda gerçekleştirilir. Worker, bu görevde uygulanır.
  • WorkRequest
    Bu sınıf, çalışanı arka planda çalıştırma isteğini gösterir. Çalışan görevinin nasıl ve ne zaman çalıştırılacağını yapılandırmak için Constraints özelliğini (cihaza takılı veya kablosuz ağa bağlı gibi) kullanarak WorkRequest kullanın. WorkRequest öğesini daha sonraki bir görevde uygularsınız.
  • WorkManager
    Bu sınıf, WorkRequest saatinizi planlayıp çalıştırır. WorkManager, belirttiğiniz isteklerin karşılanmasını sağlayarak iş isteklerini sistem kaynakları üzerindeki yükü yaymak için planlar. WorkManager öğesini daha sonraki bir görevde uygularsınız.

1. Adım: Bir çalışan oluşturun

Bu görevde, DevBytes video oynatma listesini arka planda önceden getirmek için bir Worker eklersiniz.

  1. devbyteviewer paketinin 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. CoroutineWorker sınıfından RefreshDataWorker sınıfını genişletin. context ve WorkerParameters parametrelerini 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 RefreshDataWorker sınıfındaki doWork() yöntemini geçersiz kılın.
override suspend fun doWork(): Result {
  return Result.success()
}

Bekleme işlemi, daha sonra duraklatılıp devam ettirilebilen bir işlevdir. Askıya alma işlevi, uzun süreli bir işlem yürütebilir ve ana iş parçacığını engellemeden, tamamlanmasını bekleyebilir.

2. Adım: doWork() uygulayın

Worker sınıfındaki doWork() yöntemi bir arka plan ileti dizisinde çağrılır. Yöntem eşzamanlı olarak çalışır ve ListenableWorker.Result nesnesi döndürmelidir. Android sistemi, Worker fonksiyonunun yürütmesini bitirmesi ve ListenableWorker.Result nesnesi döndürmesi için en fazla 10 dakika verir. Bu süre dolduktan sonra sistem, Worker anahtarını zorla durdurur.

ListenableWorker.Result nesnesi oluşturmak için arka plan çalışmasının tamamlanma durumunu belirtmek üzere aşağıdaki statik yöntemlerden birini çağırın:

Bu görevde ağdan DevBytes video oynatma listesini almak için doWork() yöntemini uygularsınız. Ağdaki verileri 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 ile bir VideosRepository nesnesi oluşturun ve örneklendirin.
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 üstünde, bir try bloğunun içindeki refreshVideos() yöntemini çağırın. Çalışanın ne zaman çalıştığını izlemek için bir 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 öğesini içe aktarın.

  1. Referans olması açısından tam RefreshDataWorker sınıfı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 çalışma birimini, WorkRequest ise işin nasıl ve ne zaman yapılması gerektiğini tanımlar. WorkRequest sınıfının iki somut uygulaması vardır:

  • OneTimeWorkRequest sınıfı, tek seferlik görevlere yöneliktir. (Tek seferlik bir görev yalnızca bir kez gerçekleşir.)
  • PeriodicWorkRequest sınıfı, periyodik olarak tekrarlanan periyodik işler içindir.

Görevler tek seferlik veya periyodik olabilir. Bu nedenle, sınıfı buna göre seçin. Yinelenen çalışmalar planlama hakkında daha fazla bilgi için yinelenen iş dokümanlarına bakın.

Bu görevde önceki görevde oluşturduğunuz çalışanı çalıştırmak için bir WorkRequest tanımlar ve planlarsınız.

1. Adım: Yinelenen çalışmalar oluşturun

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 işlem oluşturulduğunda Application sınıfı (veya herhangi bir Application alt sınıfı) diğer sınıflardan önce örneklenir.

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 planlaması için iyi bir yerdir.

  1. DevByteApplication sınıfında, yinelenen arka plan çalışmasını 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önteminin içinde, PeriodicWorkRequestBuilder() yöntemini kullanarak günde bir kez çalıştırılacak periyodik bir iş isteği oluşturup başlatın. Önceki görevde oluşturduğunuz RefreshDataWorker sınıfını geçin. TimeUnit.DAYS zaman birimiyle yinelenen bir 1 aralığında geçiş yapın.
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 bir WorkRequest planlayın

WorkRequest tanımladıktan sonra, enqueueUniquePeriodicWork() yöntemini kullanarak bunu WorkManager ile planlayabilirsiniz. Bu yöntem, sıraya benzersiz olarak adlandırılmış PeriodicWorkRequest eklemenize olanak tanır. Burada aynı anda yalnızca belirli bir addan PeriodicWorkRequest olabilir.

Örneğin, yalnızca bir senkronizasyon işleminin etkin olmasını isteyebilirsiniz. Bekleyen bir senkronizasyon işlemi varsa CurrentPeriodicWorkPolicy'yi kullanarak çalıştırmayı veya yeni çalışmanızla değiştirmeyi seçebilirsiniz.

WorkRequest planlamasının yolları hakkında daha fazla bilgi edinmek için WorkManager dokümanlarına bakın.

  1. RefreshDataWorker sınıfının başına bir tamamlayıcı nesne ekleyin. Bu çalışanı benzersiz bir ş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 çalışmayı planlayın. MevcutPeriodicWorkPolicy için KEEP sıralamasını iletin. repeatingRequest değerini PeriodicWorkRequest parametresi olarak iletin.
WorkManager.getInstance().enqueueUniquePeriodicWork(
       RefreshDataWorker.WORK_NAME,
       ExistingPeriodicWorkPolicy.KEEP,
       repeatingRequest)

Aynı ada sahip beklemedeki (tamamlanmamış) bir çalışma varsa ExistingPeriodicWorkPolicy.KEEP parametresi WorkManager öğesinin önceki periyodik çalışmayı tutmasını ve yeni iş isteğini silmesini sağlar.

  1. DevByteApplication sınıfının başında bir CoroutineScope nesnesi oluşturun. Dispatchers.Default oluşturucu olarak iletin.
private val applicationScope = CoroutineScope(Dispatchers.Default)
  1. DevByteApplication sınıfında, eş yordam başlatmak için delayedInit() adlı yeni bir yöntem ekleyin.
private fun delayedInit() {
   applicationScope.launch {
   }
}
  1. delayedInit() yönteminin içinde, setupRecurringWork() numaralı telefonu arayın.
  2. Kereste başlatma 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 sonuna delayedInit() yöntemi için bir arama 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 çalışmanızı hemen planlar.

    Logcat bölmesinde, iş isteğinin planlandığını ve ardından 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ığında görüntülenir. Bu nedenle, 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 1 gün olan zaman aralığını 15 dakikaya indirirsiniz. Bunu, periyodik bir iş isteğine ilişkin günlükleri görmek için yaparsınız.

  1. DevByteApplication sınıfının setupRecurringWork() yöntemindeki geçerli repeatingRequest tanımına yorum yapın. 15 dakikalık periyodik tekrarlama işlemiyle 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 filtresi uygulayın. Önceki günlükleri temizlemek için Logcat'i temizle simgesini tıklayın .
  2. Uygulamayı çalıştırın. WorkManager, yinelenen çalışmanızı hemen planlar. Logcat bölmesinde, günlüklere dikkat edin. İş isteği 15 dakikada bir çalıştırılır. Başka bir iş isteği günlüğü grubunu görmek için 15 dakika bekleyin. Uygulamayı çalışır durumda bırakabilir veya kapatabilirsiniz; iş yöneticisi çalışmaya devam etmelidir.

    Aralıkın bazen 15 dakikadan kısa, bazen de 15 dakikadan uzun olduğunu unutmayın. (Kesin süre, işletim sisteminin pil optimizasyonlarına tabidir.)
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 azaldığında, uyuyorsa veya ağ bağlantısı olmasa bile işi günde bir kez planlar. Bu, cihazın pilini ve performansını etkiler ve kötü bir kullanıcı deneyimine yol açabilir.

Bir sonraki görevinizde, kısıtlamalar ekleyerek bu sorunu ele almışsınız.

Önceki görevde, iş isteği planlamak için WorkManager adresini kullanıyordunuz. Bu görevde çalışmanın ne zaman yürütüleceğine dair ölçütler eklersiniz.

WorkRequest öğesini tanımlarken, Worker öğesinin ne zaman çalışması gerektiğiyle ilgili kısıtlamalar belirtebilirsiniz. Örneğin, çalışmanın yalnızca cihaz boşta kaldığında veya cihaz fişe takılı ve kablosuz ağa bağlıyken çalışması gerektiğini belirtmek isteyebilirsiniz. Ayrıca, yeniden deneme çalışması için bir geri yükleme politikası da belirtebilirsiniz. Desteklenen kısıtlamalar, Constraints.Builder politikasında belirlenen yöntemlerdir. Daha fazla bilgi edinmek için İş İsteklerinizi Tanımlama bölümüne bakın.

1. Adım: Bir Kısıtlama nesnesi ekleyin ve bir sınırlama ayarlayın

Bu adımda, bir Constraints nesnesi oluşturur ve nesnede bir ağ kısıtlaması kısıtlaması olan bir sınırlama belirlersiniz. (Günlükleri tek bir sınırlamayla fark etmek daha kolaydır. Daha sonraki bir adımda, başka kısıtlamalar eklersiniz.

  1. DevByteApplication sınıfında, setupRecurringWork() öğesinin başı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ü kısıtlaması eklemek için setRequiredNetworkType() yöntemini kullanın. İş isteği yalnızca cihaz sınırsız bir ağda olduğunda çalışması için UNMETERED sıralamasını 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 gerekir.

  1. DevByteApplication sınıfının setupRecurringWork() yönteminde Constraints nesnesini periyodik iş isteği (repeatingRequest) olarak ayarlayın. Kısıtlamaları ayarlamak için build() yöntem çağrısının yukarısına 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üklere dikkat edin

Bu adımda uygulamayı çalıştırır ve kısıtlanmış iş isteğinin arka planda aralıklarla çalıştırıldığını fark edersiniz.

  1. Önceden programlanmış 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 Logcat'i temizle simgesini tıklayarak önceki günlükleri temizleyin. work filtresi.
  3. Kısıtlamaların nasıl çalıştığını görebilmeniz için cihazda veya emülatörde kablosuz ağı kapatın. Mevcut kodda yalnızca bir sınırlama belirlenmiş ve isteğin yalnızca sayaçsız bir ağda çalışması gerektiği belirtilmiştir. Kablosuz bağlantı kapalı olduğundan cihaz ağa bağlı veya sayaçlı değil. Bu nedenle, söz konusu kısıtlama karşılanmaz.
  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çıp Logcat bölmesini izleyin. Şimdi planlanan ağ görevi, ağ kısıtlaması karşılandığı sürece yaklaşık 15 dakikada bir çalıştırılır.
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'a aşağıdaki kısıtlamaları eklersiniz:

  • Pil seviyesi düşük değil.
  • Cihaz şarj oluyor.
  • Cihaz boşta. Yalnızca API düzeyi 23'te (Android M) ve sonraki sürümlerde kullanılabilir.

Aşağıdakileri DevByteApplication sınıfına uygulayın.

  1. DevByteApplication sınıfında, setupRecurringWork() yönteminin içinde iş isteğinin yalnızca pil seviyesi düşük olduğunda ç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 güncelleyerek yalnızca cihaz boşta kaldığında çalışacak şekilde güncelleyin. Kısıtlamayı build() yöntem çağrısından önce ekleyin ve setRequiresDeviceIdle() yöntemini kullanın. Bu sınırlama, iş isteğini yalnızca kullanıcı cihazı etkin bir şekilde kullanmıyorsa çalıştırır. Bu özellik yalnızca Android 6.0 (Marshmallow) ve sonraki sürümlerde kullanılabildiğinden, SDK M ve üstü için bir koşul ekleyin.
.apply {
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       setRequiresDeviceIdle(true)
   }
}

constraints nesnesinin tam tanımını burada bulabilirsiniz.

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önteminde, istek aralığını günde bir kez olarak değiştirin.
val repeatingRequest = PeriodicWorkRequestBuilder<RefreshDataWorker>(1, TimeUnit.DAYS)
       .setConstraints(constraints)
       .build()

Periyodik çalışma isteğinin ne zaman planlandığını takip edebilmeniz için setupRecurringWork() yönteminin tam uygulamasını burada bulabilirsiniz.

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. Önceden planlanmış iş isteğini kaldırmak için DevBytes uygulamasını cihazınızdan veya emülatörden kaldırın.
  2. Uygulamayı çalıştırın. WorkManager, iş isteğini hemen planlar. İş isteği, tüm kısıtlamalar karşılandığında günde bir kez çalıştırılır.
  3. Bu iş isteği, uygulama yüklü olmasa bile uygulama 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 uyguladınız ve planladınız. WorkManager, işi planlayıp sistem kaynaklarını optimize ederek çalıştıracak. Kullanıcılarınız ve pilleri çok mutlu olur.

Android Studio projesi: DevBytesWorkManager.

  • WorkManager API, güvenilir bir şekilde çalıştırılması gereken ertelenebilir, eşzamansız görevler planlamayı kolaylaştırır.
  • Gerçek dünyadaki çoğu uygulamanın uzun süreli arka planda görevleri yerine getirmesi gerekir. Arka plan görevini optimize edilmiş ve verimli bir şekilde planlamak için WorkManager politikasını kullanın.
  • WorkManager kitaplığındaki ana sınıflar Worker, WorkRequest ve WorkManager şeklindedir.
  • Worker sınıfı, bir çalışma 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 çalışma birimini gerçekleştirmeye yönelik isteği temsil eder. WorkRequest, WorkManager içinde planladığınız çalışma için parametreleri belirtmenin temel sınıfıdır.
  • WorkRequest sınıfının iki somut uygulaması vardır: tek seferlik görevler için OneTimeWorkRequest ve periyodik iş istekleri için PeriodicWorkRequest.
  • WorkRequest öğesini tanımlarken, Worker öğesinin ne zaman çalıştırılması gerektiğini belirten Constraints değerini belirtebilirsiniz. Kısıtlamalar, cihazın fişe takılı olup olmadığı, boşta olup olmadığı veya kablosuz ağa bağlı olup olmadığı gibi bilgileri içerir.
  • WorkRequest öğesine kısıtlamalar eklemek için Constraints.Builder dokümanlarında listelenen ayarlanmış yöntemleri kullanın. Örneğin, cihazın pili azaldığında WorkRequest özelliğinin çalışmaması gerektiğini belirtmek için setRequiresBatteryNotLow() ayar yöntemini kullanın.
  • WorkRequest öğesini tanımladıktan sonra görevi Android sistemine aktarın. Bunu yapmak için WorkManager enqueue yöntemlerinden birini kullanarak görevi planlayın.
  • Worker öğesinin tam olarak ne zaman çalıştırılacağı, WorkRequest ve sistem optimizasyonlarında kullanılan kısıtlamalara bağlıdır. WorkManager, bu kısıtlamalar göz önünde bulundurularak mümkün olan en iyi davranışı sunacak şekilde tasarlanmıştır.

Udacity kursu:

Android geliştirici dokümanları:

Diğer:

Bu bölümde, bir eğitmen tarafından sunulan kurs kapsamında bu codelab üzerinden çalışan öğrenciler için olası ev ödevi ödevleri listelenmektedir. Öğretmenin şunları yapması gerekir:

  • Gerekirse ev ödevini atayın.
  • Öğrencilere ev ödevlerinin nasıl gönderileceğini bildirin.
  • Ev ödevlerine not verin.

Öğretmenler bu önerileri istedikleri kadar kullanabilir veya uygun görebilir ve uygun olan diğer ev ödevlerini atayabilirler.

Bu codelab'de kendiniz çalışıyorsanız, bilginizi test etmek için bu ödevlerden yararlanabilirsiniz.

1. Soru

WorkRequest sınıfının somut uygulamaları nelerdir?

makbuz 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?

makbuz setConstraints()

makbuz addConstraints()

makbuz setConstraint()

makbuz addConstraintsToWorkRequest()

Sonraki derse başlayın: 10.1 Stiller ve temalar

Bu kurstaki diğer codelab'lerin bağlantılarına ulaşmak için Android Kotlin Fundamentals codelabs açılış sayfasına göz atın.