Arka plan işlemleri bellek ve pili fazla kullanabilir. Örneğin, örtülü yayın, kaydettirilmiş birçok arka plan işlemini başlatabilir. bu süreçlerin pek işe yaramasa bile onları dinlemesi gerekir. Bu durum hem cihaz performansını hem de kullanıcı deneyimini önemli ölçüde etkileyebilir.
Bu sorunu hafifletmek için Android 7.0 (API düzeyi 24) aşağıdaki kısıtlamaları uygular:
- Android 7.0 (API düzeyi 24) ve sonraki sürümleri hedefleyen uygulamalar
CONNECTIVITY_ACTION
, şu koşulda yayın yapar: yayın alıcısını manifest dosyasında bildirmesi gerekir. Uygulamalarda kaydolurlarsaCONNECTIVITY_ACTION
yayınları alContext.registerReceiver()
ileBroadcastReceiver
ve bu bağlam hâlâ geçerlidir. - Uygulamalar
ACTION_NEW_PICTURE
veyaACTION_NEW_VIDEO
yayınları gönderemez ya da alamaz. Bu optimizasyon yalnızca Android 7.0'ı (API düzeyi 24) hedefleyen uygulamaları değil, tüm uygulamaları etkiler.
Uygulamanız bu intent'lerden herhangi birini kullanıyorsa Android 7.0 veya sonraki sürümleri çalıştıran cihazları düzgün bir şekilde hedefleyebilmek için bu intent'lere olan bağımlılıkları en kısa sürede kaldırmanız gerekir. Android çerçevesi, bu dolaylı yayınlara olan ihtiyacı azaltmak için çeşitli çözümler sunar. Örneğin, JobScheduler
ve
Yeni WorkManager ağ planlaması için sağlam mekanizmalar sağlar
belirli koşullar olduğunda yapılan işlemler (ör. sayaçsız bir ağa bağlantı)
karşılanıyor. Artık JobScheduler
uygulamasını da kullanabilirsiniz
yanıt verebilmek için iyi bir fırsattır. JobInfo
.
nesneler, JobScheduler
kullanabileceğiniz araçlardır. İşin koşulları karşılandığında sistem bu işi uygulamanızın JobService
üzerinde yürütür.
Bu sayfada, Arkadaş Bitkiler gibi alternatif yöntemleri
JobScheduler
, uygulamanızı bu yeni özelliklere uyarlama
kısıtlamalara tabi.
Kullanıcı tarafından başlatılan kısıtlamalar
Sistemdeki Pil kullanımı sayfasında ayarlar varsa kullanıcı seçeneklerden birini belirleyin:
- Kısıtlanmamış: Daha fazla pil tüketebilecek tüm arka planda çalışmalara izin verilir.
- Optimize edilmiş (varsayılan): Bir uygulamanın arka planda çalışma becerisini optimize eder. Kullanıcının uygulama ile nasıl etkileşime geçtiğine göre değişir.
- Kısıtlanmış: Uygulamanın arka planda çalışmasını tamamen engeller. Uygulamalar beklendiği gibi çalışmayabilir.
Bir uygulama, Android vitals'da açıklanan kötü davranışlardan bazılarını sergilerse sistem, kullanıcıdan söz konusu uygulamanın sistem kaynaklarına erişimini kısıtlamasını isteyebilir.
Bir uygulamanın çok fazla kaynak kullandığını fark eden sisteme bu durumu bildirir: kullanıcıya uygulama işlemlerini kısıtlama seçeneği sunar. Bildirimi tetikleyebilecek davranışlar şunlardır:
- Aşırı sayıda uyanık kalma kilidi: Ekran kapalıyken bir saat boyunca tutulan 1 kısmi uyanık kalma kilidi
- Aşırı arka plan hizmeti: Uygulama, 26'dan düşük API düzeylerini hedefliyorsa ve aşırı miktarda arka plan hizmeti
Uygulanan kısıtlamaların tam olarak ne olduğu cihaz üreticisi tarafından belirlenir. Örneğin, Android 9 (API düzeyi 28) veya sonraki sürümleri çalıştıran AOSP derlemelerinde, arka planda çalışan ve "kısıtlanmış" durumdaki uygulamalar aşağıdaki sınırlamalara tabidir:
- Ön plan hizmetleri başlatılamıyor
- Mevcut ön plan hizmetleri ön plandan kaldırılır
- Alarmlar tetiklenmiyor
- İşler yürütülmüyor
Ayrıca, bir uygulama Android 13 (API düzeyi 33) veya sonraki sürümleri hedefliyorsa ve "kısıtlanmış" durumdaysa sistem, uygulama başka nedenlerle başlatılana kadar BOOT_COMPLETED
yayınını veya LOCKED_BOOT_COMPLETED
yayınını yayınlamaz.
Belirli kısıtlamalar Güç yönetimi kısıtlamaları bölümünde listelenmiştir.
Ağ etkinliği yayınlarını almayla ilgili kısıtlamalar
Android 7.0'ı (API düzeyi 24) hedefleyen uygulamalar, manifest dosyalarında CONNECTIVITY_ACTION
yayınları almak için kaydolursa bu yayınları almaz ve bu yayına bağlı süreçler 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. Bu sorunu gidermek için çeşitli çözümler
kısıtlama mevcut olsa da doğru seçeneği
birincisi uygulamanızın ne yapmasını istediğinize bağlıdır.
Not: Context.registerReceiver()
ile kayıtlı bir BroadcastReceiver
, uygulama çalışırken bu yayınları almaya devam eder.
Sayaçsız bağlantılarda ağ işlerini planlayın
JobInfo.Builder
sınıfını kullanırken
JobInfo
nesnenizi oluşturmak için setRequiredNetworkType()
yöntemini uygulayın ve JobInfo.NETWORK_TYPE_UNMETERED
iş parametresi olarak iletin. Aşağıdaki kod örneği, cihaz sınırsız bir ağa bağlandığında ve şarj olurken bir hizmeti çalıştıracak şekilde planlar:
const val MY_BACKGROUND_JOB = 0 ... fun scheduleJob(context: Context) { val jobScheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler val job = JobInfo.Builder( MY_BACKGROUND_JOB, ComponentName(context, MyJobService::class.java) ) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setRequiresCharging(true) .build() jobScheduler.schedule(job) }
public static final int MY_BACKGROUND_JOB = 0; ... public static void scheduleJob(Context context) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo job = new JobInfo.Builder( MY_BACKGROUND_JOB, new ComponentName(context, MyJobService.class)) .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) .setRequiresCharging(true) .build(); js.schedule(job); }
İşinizin koşulları karşılandığında uygulamanız, çalıştırılması için bir geri çağırma alır
onStartJob()
yöntemini kullanarak
JobService.class
belirtilmiş. JobScheduler
uygulama örneğini görmek için JobScheduler örnek uygulamasına göz atın.
JobScheduler'ın yerine yeni bir alternatif olan WorkManager, zaman planlaması yapmanıza olanak tanıyan bir API'dir. tamamlanması gereken arka plan görevlerinin uygulama sürecinin tamamlanıp tamamlanmadığından bağımsız olarak, garanti edilen tamamlanma. İş Yöneticisi çalışması için uygun yöntemi seçer (doğrudan uygulama işleminizdeki bir iş parçacığında veya JobScheduler, Firebase JobDispatcher veya AlarmManager'ı kullanabilirsiniz). cihaz API düzeyi. Ayrıca, WorkManager, Play Hizmetleri'ni gerektirmez ve görevleri zincirleme veya görevin durumunu kontrol etme gibi bazı gelişmiş özellikleri içerir. Daha fazla bilgi için WorkManager başlıklı makaleyi inceleyin.
Uygulama çalışırken ağ bağlantısını izleme
Çalışmakta olan uygulamalar, CONNECTIVITY_CHANGE
dinlemek için şuna sahip olabilir:
kayıtlı: BroadcastReceiver
. Ancak ConnectivityManager
API, yalnızca belirtilen ağ koşulları karşılandığında geri arama isteğinde bulunmak için daha sağlam bir yöntem sağlar.
NetworkRequest
nesneleri,
NetworkCapabilities
kapsamında ağ geri çağırması. NetworkRequest.Builder
sınıfıyla NetworkRequest
nesnesi oluşturdunuz. registerNetworkCallback()
.
ardından NetworkRequest
nesnesini sisteme iletir. Zaman
Ağ koşulları karşılandığında, uygulama
onAvailable()
yöntemi, ConnectivityManager.NetworkCallback
sınıfında tanımlandı.
Uygulama, uygulamadan çıkılana veya unregisterNetworkCallback()
çağrılana kadar geri çağırmalar almaya devam eder.
Resim ve video yayınlarını almayla ilgili kısıtlamalar
Android 7.0'da (API düzeyi 24) uygulamalar, ACTION_NEW_PICTURE
veya ACTION_NEW_VIDEO
yayınlarını gönderip alamaz. Bu kısıtlama
birden fazla uygulamanın zorunlu hale gelmesi durumunda performans ve kullanıcı deneyimi
yeni bir görüntü veya video işlemek için uyanık kalmalıdır. Android 7.0 (API düzeyi 24)
JobInfo
ve JobParameters
kapsamını genişleterek alternatif bir çözüm sunar.
İçerik URI'si değişikliklerinde işleri tetikleme
Android 7.0 (API düzeyi 24), içerik URI'si değişiklikleriyle ilgili işleri tetiklemek için
JobInfo
API'yi aşağıdaki yöntemlerle kullanabilirsiniz:
-
JobInfo.TriggerContentUri()
- İçerik URI'si değişikliklerinde bir işi tetiklemek için gereken parametreleri kapsar.
-
JobInfo.Builder.addTriggerContentUri()
- .
JobInfo
adlı cihazaTriggerContentUri
nesnesi iletir.ContentObserver
kapsüllenen içerik URI'sini izler. Bir işle ilişkili birden fazlaTriggerContentUri
nesnesi varsa sistem bir geri çağırması için de kullanılır. ziyaret edin.
-
Şuna
TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS
işaretini ekle: belirtilen URI'nin alt öğeleri değişirse işi tetikler. Bu işaretregisterContentObserver()
parametresine iletilennotifyForDescendants
parametresine karşılık gelir.
Not: TriggerContentUri()
kullanılamaz
setPeriodic()
veya setPersisted()
ile kombinasyonu. İçerik değişikliklerini sürekli olarak izlemek için uygulamanın JobService
en son geri aramayı işlemesi tamamlanmadan önce yeni bir JobInfo
planlayın.
Aşağıdaki örnek kod, sistem MEDIA_URI
içerik URI'sinde bir değişiklik bildirdiğinde tetiklenecek bir iş planlar:
const val MY_BACKGROUND_JOB = 0 ... fun scheduleJob(context: Context) { val jobScheduler = context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler val job = JobInfo.Builder( MY_BACKGROUND_JOB, ComponentName(context, MediaContentJob::class.java) ) .addTriggerContentUri( JobInfo.TriggerContentUri( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS ) ) .build() jobScheduler.schedule(job) }
public static final int MY_BACKGROUND_JOB = 0; ... public static void scheduleJob(Context context) { JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); JobInfo.Builder builder = new JobInfo.Builder( MY_BACKGROUND_JOB, new ComponentName(context, MediaContentJob.class)); builder.addTriggerContentUri( new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)); js.schedule(builder.build()); }
Sistem, belirtilen içerik URI'lerinde bir değişiklik bildirdiğinde uygulamanıza geri çağırma çağrısı gönderilir ve MediaContentJob.class
içindeki onStartJob()
yöntemine bir JobParameters
nesnesi iletilir.
Hangi içerik yetkililerinin bir işi tetiklediğini belirleme
Android 7.0 (API düzeyi 24), JobParameters
'ü genişleterek uygulamanızın hangi içerik yetkililerinin ve URI'lerin işi tetiklediğiyle ilgili yararlı bilgiler almasına olanak tanır:
-
Uri[] getTriggeredContentUris()
-
İşi tetikleyen URI dizisini döndürür. Hiçbir URI işi tetiklemediyse (örneğin iş,
null
bir son teslim tarihi veya başka bir nedenden dolayı tetiklenmiş olması) ya da URI'lar 50'den büyük. -
String[] getTriggeredContentAuthorities()
- .
İşi tetikleyen içerik yetkililerinin dize dizisini döndürür.
Döndürülen dizi
null
değilse hangi URI'lerin değiştiğine dair ayrıntıları almak içingetTriggeredContentUris()
'ü kullanın.
Aşağıdaki örnek kod, JobService.onStartJob()
yöntemini geçersiz kılar ve
işi tetikleyen içerik yetkililerini ve URI'ları kaydeder:
override fun onStartJob(params: JobParameters): Boolean { StringBuilder().apply { append("Media content has changed:\n") params.triggeredContentAuthorities?.also { authorities -> append("Authorities: ${authorities.joinToString(", ")}\n") append(params.triggeredContentUris?.joinToString("\n")) } ?: append("(No content)") Log.i(TAG, toString()) } return true }
@Override public boolean onStartJob(JobParameters params) { StringBuilder sb = new StringBuilder(); sb.append("Media content has changed:\n"); if (params.getTriggeredContentAuthorities() != null) { sb.append("Authorities: "); boolean first = true; for (String auth : params.getTriggeredContentAuthorities()) { if (first) { first = false; } else { sb.append(", "); } sb.append(auth); } if (params.getTriggeredContentUris() != null) { for (Uri uri : params.getTriggeredContentUris()) { sb.append("\n"); sb.append(uri); } } } else { sb.append("(No content)"); } Log.i(TAG, sb.toString()); return true; }
Uygulamanızı daha da optimize edin
Uygulamalarınızı, düşük bellek kapasitesine sahip 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'te kayıtlı, gizli yayın alıcılarına olan bağımlılıkları kaldırmak, uygulamanızın bu tür cihazlarda daha iyi çalışmasını sağlayabilir. Her ne kadar Android 7.0 (API düzeyi 24) bu sorunlardan bazılarını azaltmak için adımlar atmaktadır. uygulamanızı bu uygulamaları kullanmadan çalışacak şekilde optimize etmenizi arka plan işlemlerine sahip olmayabilir.
Aşağıdaki Android Debug Bridge (ADB) komutları, arka plan işlemleri devre dışıyken uygulama davranışını test etmenize yardımcı olabilir:
- Örtük 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ük 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
- Kullanıcının, uygulamanızı arka planda pil kullanımı için "kısıtlanmış" duruma getirmesini simüle edebilirsiniz. Bu ayar, uygulamanızın çalışmasını engeller arka planda çalışır. Bunu yapmak için bir terminal penceresinde aşağıdaki komutu çalıştırın:
-
$ adb shell cmd appops set <PACKAGE_NAME> RUN_ANY_IN_BACKGROUND deny