Arka plan görevleriyle ilgili sistem kısıtlamaları

Arka plan işlemleri, bellek ve pil açısından yoğun olabilir. Örneğin, örtülü bir yayın, çok fazla iş yapmayacak olsalar bile dinlemek için kaydolan birçok arka plan işlemini başlatabilir. Bu durum hem cihaz performansını hem de kullanıcı deneyimini önemli ölçüde etkileyebilir.

Sistem kısıtlamalarıyla karşılaşmamak için arka plan görevinizde doğru API'yi kullandığınızdan emin olun. Arka plan görevlerine genel bakış dokümanı, ihtiyaçlarınıza uygun API'yi seçmenize yardımcı olur.

Kullanıcı tarafından başlatılan kısıtlamalar

Bir uygulama, Android vitals'da açıklanan kötü davranışlardan bazılarını sergilerse sistem, kullanıcıdan bu uygulamanın sistem kaynaklarına erişimini kısıtlamasını ister.

Sistem, bir uygulamanın aşırı kaynak tükettiğini fark ederse kullanıcıyı bilgilendirir ve kullanıcının uygulamanın işlemlerini kısıtlamasına olanak tanır. Bildirimi tetikleyebilecek davranışlar şunlardır:

  1. Aşırı sayıda uyanık kalma kilidi: Ekran kapalıyken bir saat boyunca tutulan 1 kısmi uyanık kalma kilidi
  2. Aşırı arka plan hizmetleri: Uygulama, API düzeyi 26'dan düşük sürümleri hedefliyorsa ve aşırı arka plan hizmeti kullanıyorsa

Uygulanan kısıtlamalar, cihaz üreticisi tarafından belirlenir. Örneğin, AOSP derlemelerinde kısıtlanmış uygulamalar, ön planda olmadıkları sürece işleri çalıştıramaz, alarm tetikleyemez veya ağı kullanamaz.

Ağ etkinliği yayınlarını alma kısıtlamaları

Uygulamalar, manifest dosyalarında bu yayınları alacak şekilde kaydolursa CONNECTIVITY_ACTION yayınlarını almaz ve bu yayına bağlı işlemler başlatılmaz. Bu durum, cihaz bir sınırsız ağa bağlandığında ağ değişikliklerini dinlemek veya toplu ağ etkinlikleri gerçekleştirmek isteyen uygulamalar için sorun oluşturabilir. Android çerçevesinde bu kısıtlamayı aşmak için çeşitli çözümler mevcuttur ancak doğru çözümü seçmek, uygulamanızın ne yapmasını istediğinize bağlıdır.

Sınırsız bağlantılarda çalışmayı planlama

WorkRequest oluştururken NetworkType.UNMETERED Constraint ekleyin.

fun scheduleWork(context: Context) {
    val workManager = WorkManager.getInstance(context)
    val workRequest = OneTimeWorkRequestBuilder<MyWorker>()
       .setConstraints(
           Constraints.Builder()
               .setRequiredNetworkType(NetworkType.UNMETERED)
               .build()
           )
       .build()

    workManager.enqueue(workRequest)
}

Çalışmanızın koşulları karşılandığında uygulamanız, belirtilen Worker sınıfında doWork() yöntemini çalıştırmak için geri çağırma alır.

Uygulama çalışırken ağ bağlantısını izleme

Çalışan uygulamalar, kayıtlı bir BroadcastReceiver ile CONNECTIVITY_CHANGE dinlemeye devam edebilir. Ancak ConnectivityManager API, yalnızca belirtilen ağ koşulları karşılandığında geri arama isteğinde bulunmak için daha güçlü bir yöntem sağlar.

NetworkRequest nesneleri, NetworkCapabilities açısından ağ geri çağırma parametrelerini tanımlar. NetworkRequest.Builder sınıfıyla NetworkRequest nesneleri oluşturursunuz. registerNetworkCallback, daha sonra NetworkRequest nesnesini sisteme iletir. Ağ koşulları karşılandığında uygulama, onAvailable() sınıfında tanımlanan ConnectivityManager.NetworkCallback yöntemini yürütmek için geri çağırma alır.

Uygulama çıkana veya unregisterNetworkCallback() çağrılana kadar geri çağırmalar almaya devam eder.

Resim ve video yayınları alma kısıtlamaları

Uygulamalar ACTION_NEW_PICTURE veya ACTION_NEW_VIDEO yayınlarını gönderemez ya da alamaz. Bu kısıtlama, yeni bir resim veya videonun işlenmesi için birden fazla uygulamanın uyandırılması gerektiğinde performans ve kullanıcı deneyimi üzerindeki etkileri azaltmaya yardımcı olur.

Hangi içerik yetkililerinin işi tetiklediğini belirleme

WorkerParameters, uygulamanızın hangi içerik yetkililerinin ve URI'lerin çalışmayı tetiklediği hakkında faydalı bilgiler almasına olanak tanır:

List<Uri> getTriggeredContentUris()

Çalışmayı tetikleyen URI'lerin listesini döndürür. Bu alan, işi tetikleyen URI yoksa (ör. iş, bir son tarih veya başka bir nedenle tetiklendiyse) ya da değiştirilen URI sayısı 50'den fazlaysa boş olur.

List<String> getTriggeredContentAuthorities()

Çalışmayı tetikleyen içerik yetkililerinin dize listesini döndürür. Döndürülen liste boş değilse hangi URI'lerin değiştiğinin ayrıntılarını almak için getTriggeredContentUris() öğesini kullanın.

Aşağıdaki örnek kod, CoroutineWorker.doWork() yöntemini geçersiz kılar ve işi tetikleyen içerik yetkililerini ve URI'leri kaydeder:

class MyWorker(
    appContext: Context,
    params: WorkerParameters
): CoroutineWorker(appContext, params)
    override suspend fun doWork(): Result {
        StringBuilder().apply {
            append("Media content has changed:\n")
            params.triggeredContentAuthorities
                .takeIf { it.isNotEmpty() }
                ?.let { authorities ->
                    append("Authorities: ${authorities.joinToString(", ")}\n")
                    append(params.triggeredContentUris.joinToString("\n"))
                } ?: append("(No content)")
            Log.i(TAG, toString())
        }
        return Result.success()
    }
}

Uygulamayı sistem kısıtlamaları altında test etme

Uygulamalarınızı düşük bellekli cihazlarda veya düşük bellek koşullarında çalışacak şekilde optimize etmek, performansı ve kullanıcı deneyimini iyileştirebilir. Arka plan hizmetlerine ve manifestte kayıtlı dolaylı yayın alıcılarına olan bağımlılıkların kaldırılması, uygulamanızın bu tür cihazlarda daha iyi çalışmasına yardımcı olabilir. Uygulamanızı, bu arka plan işlemlerini hiç kullanmadan çalışacak şekilde optimize etmeniz önerilir.

Android Debug Bridge (ADB) ile ilgili bazı ek komutlar, uygulama davranışını bu arka plan işlemleri devre dışıyken test etmenize yardımcı olabilir:

  • Örtülü yayınların ve arka plan hizmetlerinin kullanılamadığı koşulları simüle etmek için aşağıdaki komutu girin:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND ignore

  • Örtülü yayınları ve arka plan hizmetlerini yeniden etkinleştirmek için aşağıdaki komutu girin:

    $ adb shell cmd appops set <package_name> RUN_IN_BACKGROUND allow

Uygulamanızı daha fazla optimize etme

Arka plan görevlerinizin davranışını optimize etmenin diğer iyi yolları için Görev planlama API'leri için pil kullanımını optimize etme dokümanına bakın.