Aracılığıyla paylaş


Android İş Zamanlayıcısı

Bu kılavuzda, Android 5.0 (API düzeyi 21) ve üzeri çalıştıran Android cihazlarda kullanılabilen Android İş Zamanlayıcı API'sini kullanarak arka plan çalışmasının nasıl zamanlandığı açıklanır.

Genel bakış

Android uygulamasını kullanıcıya duyarlı tutmanın en iyi yollarından biri, karmaşık veya uzun süre çalışan işlerin arka planda gerçekleştirilmesini sağlamaktır. Ancak, arka plan çalışmalarının kullanıcının cihazdaki deneyimini olumsuz etkilememesi önemlidir.

Örneğin arka plan işi, belirli bir veri kümesindeki değişiklikleri sorgulamak için her üç veya dört dakikada bir bir web sitesini yoklayabilir. Bu iyi huylu görünüyor, ancak pil ömrü üzerinde felaket bir etkiye sahip olabilir. Uygulama cihazı tekrar tekrar uyandırır, CPU'yu daha yüksek bir güç durumuna yükseltecek, radyoları güçlendirecek, ağ isteklerini yapacak ve ardından sonuçları işleyecek. Cihaz hemen kapanmayacağından ve düşük güçte boşta kalma durumuna geri dönmeyeceği için durum daha da kötüleşir. Kötü zamanlanmış arka plan çalışması, cihazı yanlışlıkla gereksiz ve aşırı güç gereksinimleri olan bir durumda tutabilir. Bu görünüşte masum bir etkinlik (bir web sitesini yoklama), cihazı nispeten kısa bir süre içinde kullanılamaz hale getirir.

Android, arka planda iş gerçekleştirmeye yardımcı olmak için aşağıdaki API'leri sağlar, ancak kendi başlarına akıllı iş zamanlama için yeterli değildir.

  • Intent Services – Intent Services, işi gerçekleştirmek için mükemmeldir, ancak çalışmayı zamanlamanın hiçbir yolunu sağlamaz.
  • AlarmManager – Bu API'ler yalnızca işin zamanlamasına izin verir, ancak çalışmayı gerçekleştirmek için hiçbir yol sağlamaz. Ayrıca, AlarmManager yalnızca zamana bağlı kısıtlamalara izin verir, yani belirli bir zamanda veya belirli bir süre geçtikten sonra alarm tetikler.
  • Yayın Alıcıları – Android uygulaması, sistem genelindeki olaylara veya Amaçlara yanıt olarak iş gerçekleştirmek için yayın alıcılarını ayarlayabilir. Ancak, yayın alıcıları işin ne zaman çalıştırılacağı üzerinde herhangi bir denetim sağlamaz. Ayrıca Android işletim sistemindeki değişiklikler, yayın alıcılarının ne zaman çalışacağını veya yanıt verebilecekleri iş türlerini kısıtlar.

Arka plan çalışmalarını verimli bir şekilde gerçekleştirmek için iki önemli özellik vardır (bazen arka plan işi veya olarak da adlandırılır):

  1. İşi akıllı bir şekilde zamanlama – Bir uygulama arka planda çalışırken bunu iyi bir vatandaş olarak yapması önemlidir. İdeal olan, uygulamanın bir işin çalıştırılmasını istememesidir. Bunun yerine, uygulamanın işin ne zaman çalıştırılacağına ilişkin karşılanması gereken koşulları belirtmesi ve ardından bu işi koşullar karşılandığında işi gerçekleştirecek işletim sistemiyle zamanlaması gerekir. Bu, Android'in cihazda maksimum verimlilik sağlamak için işi çalıştırmasına olanak tanır. Örneğin ağ istekleri, ağ ile ilgili ek yüklerden en yüksek düzeyde yararlanmak için tümünü aynı anda çalıştıracak şekilde toplu işlenebilir.
  2. Çalışmayı kapsülleme – Arka plan çalışmasını gerçekleştirme kodu, kullanıcı arabiriminden bağımsız olarak çalıştırılabilen ayrık bir bileşende kapsüllenmelidir ve çalışmanın bir nedenle tamamlanamaması durumunda yeniden zamanlanması nispeten kolay olacaktır.

Android İş Zamanlayıcı, arka plan çalışmasını zamanlamayı basitleştirmek için akıcı bir API sağlayan Android işletim sisteminde yerleşik bir çerçevedir. Android İş Zamanlayıcı aşağıdaki türlerden oluşur:

  • Android.App.Job.JobScheduler, bir Android uygulaması adına işleri zamanlamak, yürütmek ve gerekirse iptal etmek için kullanılan bir sistem hizmetidir.
  • , Android.App.Job.JobService işi uygulamanın ana iş parçacığında çalıştıracak mantıkla genişletilmesi gereken soyut bir sınıftır. Bu, JobService çalışmanın zaman uyumsuz olarak nasıl gerçekleştirilecek olduğundan sorumlu olduğu anlamına gelir.
  • Bir Android.App.Job.JobInfo nesne, işin çalışması gerektiğinde Android'e yol gösterecek ölçütleri içerir.

Android İş Zamanlayıcı ile çalışmayı zamanlamak için, Xamarin.Android uygulamasının kodu sınıfını genişleten JobService bir sınıfta kapsüllemelidir. JobService işin ömrü boyunca çağrılabilecek üç yaşam döngüsü yöntemi vardır:

  • bool OnStartJob(JobParameters parametreleri) – Bu yöntem, iş gerçekleştirmek için tarafından JobScheduler çağrılır ve uygulamanın ana iş parçacığında çalışır. İşi zaman uyumsuz olarak gerçekleştirmek ve kalan iş varsa veya false iş yapıldıysa geri dönmek true öğesinin sorumluluğundadırJobService.

    JobScheduler Bu yöntemi çağırdığında, iş süresi boyunca Android'den bir uyandırma kilidi talep eder ve korur. İş tamamlandığında, yöntemini çağırarak bu olguyu JobScheduler bildirmek (bundan sonra açıklanmıştır) öğesinin JobFinished sorumluluğundadırJobService.

  • JobFinished(JobParameters parametreleri, bool needsReschedule) – Bu yöntem, işin tamamlandığını bildirmek JobScheduler için tarafından JobService çağrılmalıdır. Çağrılmazsa JobFinished , JobScheduler uyandırma kilidi kaldırılmaz ve gereksiz pil boşalmasına neden olur.

  • bool OnStopJob(JobParameters parametreleri) – İş Android tarafından erken durdurulduğunda bu çağrılır. İşin yeniden deneme ölçütlerine göre yeniden zamanlanması gerekiyorsa döndürülmelidir true (aşağıda daha ayrıntılı olarak ele alınmalıdır).

Bir işin ne zaman çalıştırılacağını veya ne zaman çalıştırılacağını denetleyecek kısıtlamaları veya tetikleyicileri belirtmek mümkündür. Örneğin, bir işi, yalnızca cihaz şarj olduğunda çalışacak şekilde sınırlandırmak veya bir resim çekildiğinde bir iş başlatmak mümkündür.

Bu kılavuzda bir sınıfın nasıl uygulanacağı ve ile JobSchedulernasıl zamanlanacağı ayrıntılı olarak JobService ele alınacaktır.

Gereksinimler

Android İş Zamanlayıcı için Android API düzeyi 21 (Android 5.0) veya üzeri gerekir.

Android İş Zamanlayıcı'yı kullanma

Android JobScheduler API'sini kullanmanın üç adımı vardır:

  1. İşi kapsüllemek için bir JobService türü uygulayın.
  2. İşi çalıştırma ölçütlerini JobInfo tutacak nesneyi oluşturmak için JobScheduler bir JobInfo.Builder nesnesi kullanın.
  3. kullanarak JobScheduler.Scheduleişi zamanlayın.

JobService Uygulama

Android İş Zamanlayıcı kitaplığı tarafından gerçekleştirilen tüm çalışmalar soyut sınıfını genişleten Android.App.Job.JobService bir türde yapılmalıdır. JobService Oluşturma işlemi, Android çerçevesiyle oluşturma Service işlemine çok benzer:

  1. Sınıfını JobService genişletin.
  2. alt sınıfı ile ServiceAttribute süsleyin ve parametresini Name paket adından ve sınıfın adından oluşan bir dizeye ayarlayın (aşağıdaki örne bakın).
  3. Permission üzerindeki ServiceAttribute özelliğini dizesine android.permission.BIND_JOB_SERVICEayarlayın.
  4. OnStartJob yöntemini geçersiz kılarak işi gerçekleştirmek için kodu ekleyin. Android, işi çalıştırmak için uygulamanın ana iş parçacığında bu yöntemi çağırır. Uygulamanın engellenmesini önlemek için bir iş parçacığında birkaç milisaniyenin gerçekleştirilmesi daha uzun sürecek çalışmalar.
  5. İş tamamlandığında yöntemini JobService çağırması JobFinished gerekir. Bu yöntem, işin tamamlandığını nasıl JobService bildirir JobScheduler . Arama JobFinished yapılmaması, cihaza gereksiz talepler göndermeye ve pil ömrünü kısaltmaya neden JobService olur.
  6. Yöntemini geçersiz kılmak OnStopJob da iyi bir fikirdir. İş tamamlanmadan kapatılırken bu yöntem Android tarafından çağrılır ve tüm kaynakları düzgün bir şekilde atma fırsatı sağlar JobService . İşin yeniden zamanlanmış olması gerekiyorsa veya false işi yeniden çalıştırmak istenmiyorsa bu yöntem döndürülmelidirtrue.

Aşağıdaki kod, bazı işleri zaman uyumsuz olarak gerçekleştirmek için TPL kullanan bir uygulama için en JobService basit örnektir:

[Service(Name = "com.xamarin.samples.downloadscheduler.DownloadJob", 
         Permission = "android.permission.BIND_JOB_SERVICE")]
public class DownloadJob : JobService
{
    public override bool OnStartJob(JobParameters jobParams)
    {            
        Task.Run(() =>
        {
            // Work is happening asynchronously
                      
            // Have to tell the JobScheduler the work is done. 
            JobFinished(jobParams, false);
        });

        // Return true because of the asynchronous work
        return true;  
    }

    public override bool OnStopJob(JobParameters jobParams)
    {
        // we don't want to reschedule the job if it is stopped or cancelled.
        return false; 
    }
}

İş zamanlamak için JobInfo oluşturma

Xamarin.Android uygulamaları doğrudan bir JobService örneği oluşturmaz, bunun yerine nesnesine JobSchedulergeçirirJobInfo. , JobScheduler istenen JobService nesnenin örneğini oluşturur, içindeki meta verilere JobInfogöre öğesini zamanlar ve çalıştırırJobService. Bir JobInfo nesne aşağıdaki bilgileri içermelidir:

  • JobId – bu, int bir işi JobScheduleriçin tanımlamak için kullanılan bir değerdir. Bu değerin yeniden kullanılması mevcut işleri güncelleştirir. Değer uygulama için benzersiz olmalıdır.
  • JobService – bu parametre, bir işi çalıştırmak için kullanması gereken türü JobScheduler açıkça tanımlayan bir parametredirComponentName.

Bu uzantı yöntemi, Etkinlik gibi bir Android Contextile nasıl oluşturulacağını JobInfo.Builder gösterir:

public static class JobSchedulerHelpers
{
    public static JobInfo.Builder CreateJobBuilderUsingJobId<T>(this Context context, int jobId) where T:JobService
    {
        var javaClass = Java.Lang.Class.FromType(typeof(T));
        var componentName = new ComponentName(context, javaClass);
        return new JobInfo.Builder(jobId, componentName);
    }
}

// Sample usage - creates a JobBuilder for a DownloadJob and sets the Job ID to 1.
var jobBuilder = this.CreateJobBuilderUsingJobId<DownloadJob>(1);

var jobInfo = jobBuilder.Build();  // creates a JobInfo object.

Android İş Zamanlayıcı'nın güçlü özelliklerinden biri, işin ne zaman veya hangi koşullar altında çalışabileceğini denetleyebilme özelliğidir. Aşağıdaki tabloda, bir uygulamanın bir işin ne zaman çalışabileceğini etkilemesine olanak sağlayan bazı yöntemler JobInfo.Builder açıklanmaktadır:

Metot Açıklama
SetMinimumLatency bir iş çalıştırılmadan önce gözlemlenmesi gereken bir gecikme (milisaniye cinsinden) belirtir.
SetOverridingDeadline bu süre (milisaniye cinsinden) tamamlanmadan önce işin çalıştırılması gerektiğini bildirir.
SetRequiredNetworkType bir işin ağ gereksinimlerini belirtir.
SetRequiresBatteryNotLow İş yalnızca cihaz kullanıcıya "düşük pil" uyarısı görüntülemediğinde çalıştırılabilir.
SetRequiresCharging İş yalnızca pil şarj olduğunda çalıştırılabilir.
SetDeviceIdle İş, cihaz meşgul olduğunda çalışır.
SetPeriodic İşin düzenli olarak çalıştırılması gerektiğini belirtir.
SetPersisted İş, cihaz yeniden başlatmaları arasında perisist olmalıdır.

, SetBackoffCriteria bir işi yeniden çalıştırmaya çalışmadan önce beklemesi JobScheduler gereken süreyle ilgili bazı yönergeler sağlar. Geri alma ölçütlerinin iki bölümü vardır: milisaniye cinsinden gecikme (varsayılan değer 30 saniye) ve kullanılması gereken geri alma türü (bazen geri alma ilkesi veya yeniden deneme ilkesi olarak adlandırılır). İki ilke enum içinde Android.App.Job.BackoffPolicy kapsüllenir:

  • BackoffPolicy.Exponential – Üstel geri alma ilkesi, her hatadan sonra ilk geri alma değerini üstel olarak artırır. bir iş ilk kez başarısız olduğunda, kitaplık işi yeniden zamanlamadan önce belirtilen ilk aralığı (örneğin 30 saniye) bekler. İş ikinci kez başarısız olduğunda, kitaplık işi çalıştırmaya çalışmadan önce en az 60 saniye bekler. Üçüncü başarısız denemeden sonra kitaplık 120 saniye bekler ve bu şekilde devam eder. Bu varsayılan değerdir.
  • BackoffPolicy.Linear – Bu strateji, işin belirlenen aralıklarla (başarılı olana kadar) çalışacak şekilde yeniden zamanlanması gereken doğrusal bir geri almadır. Doğrusal geri alma, mümkün olan en kısa sürede tamamlanması gereken çalışmalar veya kendilerini hızlı bir şekilde çözecek sorunlar için uygundur.

Nesne oluşturma JobInfo hakkında daha fazla bilgi için lütfen Google'ın sınıfla ilgili JobInfo.Builder belgelerini okuyun.

JobInfo aracılığıyla bir işe parametre geçirme

Parametreler, yöntemiyle Job.Builder.SetExtras birlikte geçirilen bir PersistableBundle oluşturularak bir işe geçirilir:

var jobParameters = new PersistableBundle();
jobParameters.PutInt("LoopCount", 11);

var jobBuilder = this.CreateJobBuilderUsingJobId<DownloadJob>(1)
                     .SetExtras(jobParameters)
                     .Build();

PersistableBundle yöntemindeki JobServiceOnStartJob özelliğinden Android.App.Job.JobParameters.Extras erişilir:

public override bool OnStartJob(JobParameters jobParameters)
{
    var loopCount = jobParams.Extras.GetInt("LoopCount", 10);
    
    // rest of code omitted
} 

İşi zamanlama

Bir işi zamanlamak için, bir Xamarin.Android uygulaması sistem hizmetine bir başvuru JobScheduler alır ve önceki adımda oluşturulan nesneyle JobInfo yöntemini çağırırJobScheduler.Schedule. JobScheduler.Schedule iki tamsayı değerinden biriyle hemen döndürür:

  • JobScheduler.ResultSuccess – İş başarıyla zamanlandı.
  • JobScheduler.ResultFailure – İş zamanlanamadı. Bu durum genellikle çakışan JobInfo parametrelerden kaynaklanır.

Bu kod, bir işi zamanlamanın ve kullanıcıya zamanlama girişiminin sonuçlarını bildirmenin bir örneğidir:

var jobScheduler = (JobScheduler)GetSystemService(JobSchedulerService);
var scheduleResult = jobScheduler.Schedule(jobInfo);

if (JobScheduler.ResultSuccess == scheduleResult)
{
    var snackBar = Snackbar.Make(FindViewById(Android.Resource.Id.Content), Resource.String.jobscheduled_success, Snackbar.LengthShort);
    snackBar.Show();
}
else
{
    var snackBar = Snackbar.Make(FindViewById(Android.Resource.Id.Content), Resource.String.jobscheduled_failure, Snackbar.LengthShort);
    snackBar.Show();
}

bir işi iptal etme

Yöntemini veya yöntemini JobScheduler.Cancel(jobId) kullanarak JobsScheduler.CancelAll() zamanlanmış tüm işleri veya yalnızca tek bir işi iptal etmek mümkündür:

// Cancel all jobs
jobScheduler.CancelAll(); 

// to cancel a job with jobID = 1
jobScheduler.Cancel(1)

Özet

Bu kılavuzda, arka planda akıllı bir şekilde iş yapmak için Android İş Zamanlayıcı'nın nasıl kullanılacağı açıklanmıştır. Bu makalede, bir olarak JobService gerçekleştirilecek işin nasıl kapsülleneceğini ve öğesinin bu çalışmayı zamanlamak için nasıl kullanılacağı JobScheduler , ölçütün bir JobTrigger ile birlikte belirtilmesi ve hataların bir RetryStrategyile nasıl işlenmesi gerektiği anlatıldı.