Arka planda çalışmayla ilgili sistem kısıtlamaları

Arka plan işlemleri, bellek ve pil yoğun olabilir. Örneğin, örtülü bir yayın, fazla işe yaramasa bile, izlemek üzere kaydedilmiş birçok arka plan işlemi başlatabilir. Bunun hem cihaz performansı hem de kullanıcı deneyimi üzerinde önemli bir etkisi olabilir.

Sistem kısıtlamalarından kaçınmak için arka plan görevinize uygun API'yi kullandığınızdan emin olun. Arka plan görevlerine genel bakış belgeleri, ihtiyaçlarınız için doğru API'yi seçmenize yardımcı olur.

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

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

Sistem, bir uygulamanın aşırı kaynak kullandığını tespit ederse kullanıcıyı bilgilendirir ve uygulamanın işlemlerini kısıtlama seçeneği sunar. Bildirimi tetikleyebilecek davranışlar arasında şunlar yer alır:

  1. Aşırı sayıda uyanık kalma kilidi: Ekran kapalıyken bir saat süreyle tutulan 1 kısmi uyanık kalma kilidi
  2. Aşırı düzeyde arka plan hizmeti: Uygulama 26'dan düşük API düzeylerini hedefliyorsa ve aşırı miktarda arka plan hizmetine sahipse

Uygulanan kesin kısıtlamalar cihaz üreticisi tarafından belirlenir. Örneğin, AOSP derlemelerinde kısıtlanmış uygulamalar, ön plandaki uygulamalar dışında iş çalıştıramaz, alarm tetikleyemez veya ağı kullanamaz.

Ağ etkinliği yayınlarını almayla ilgili kısıtlamalar

Uygulamalar, manifest dosyalarında almak için kaydolursa CONNECTIVITY_ACTION yayınlarını almaz ve bu yayına bağlı olan işlemler başlamaz. Bu durum, cihaz sınırsız bir 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şmaya yönelik birçok çözüm halihazırda mevcuttur, ancak doğru çözümün seçilmesi, uygulamanızın neyi başarmasını istediğinize bağlıdır.

Sayaçsız bağlantılarda çalışma 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 bir geri çağırma alır.

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

Çalışan uygulamalar, kayıtlı bir BroadcastReceiver ile CONNECTIVITY_CHANGE dinlemeyi sürdürebilir. Bununla birlikte ConnectivityManager API, yalnızca belirtilen ağ koşulları karşılandığında geri çağırma isteğinde bulunmak için daha güçlü bir yöntem sunar.

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

Uygulama, uygulama çıkış yapana veya unregisterNetworkCallback() yöntemini çağırana kadar geri çağırmaları almaya devam eder.

Görüntü ve video yayınlarını almayla ilgili kısıtlamalar

Uygulamalar ACTION_NEW_PICTURE veya ACTION_NEW_VIDEO yayınlarını gönderemez veya alamaz. Bu kısıtlama, yeni bir resmi veya videoyu işlemek için bazı uygulamaların uyanması gerektiğinde performans ve kullanıcı deneyimi üzerindeki etkileri hafifletmeye yardımcı olur.

Hangi içerik yetkililerinin işleri tetiklediğini belirleyin

WorkerParameters, uygulamanızın işi tetikleyen içerik yetkilileri ve URI'ler hakkında faydalı bilgiler almasına olanak tanır:

List<Uri> getTriggeredContentUris()

İşi tetikleyen URI'ların listesini döndürür. Çalışmayı hiçbir URI tetiklemediyse (örneğin, iş son tarih nedeniyle veya başka bir nedenden dolayı tetiklendiyse) ya da değiştirilen URI'ların sayısı 50'den fazlaysa bu alan boş olur.

List<String> getTriggeredContentAuthorities()

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

Aşağıdaki örnek kod, CoroutineWorker.doWork() yöntemini geçersiz kılar ve işi tetikleyen içerik yetkililerini ve URI'ları 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()
    }
}

Sistem kısıtlamaları altında test uygulaması

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 manifest kayıtlı örtülü yayın alıcılarına olan bağımlılıkları kaldırmak, uygulamanızın bu tür cihazlarda daha iyi çalışmasına yardımcı olabilir. Uygulamanızı, bu arka plan işlemlerini tamamen kullanmadan çalışacak şekilde optimize etmeniz önerilir.

Bazı ek Android Debug Bridge (ADB) komutları, bu arka plan işlemleri devre dışıyken uygulama davranışını 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 da optimize edin

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