Arka planda çalışan uygulamalar, cihazın sınırlı kaynaklarından (ör. RAM) bazılarını tüketir. Bu durum, özellikle kullanıcı oyun oynama veya video izleme gibi yoğun kaynak kullanan bir uygulama kullanıyorsa kullanıcı deneyiminin bozulmasına neden olabilir. Android 8.0 (API düzeyi 26), kullanıcı deneyimini iyileştirmek için uygulamaların arka planda çalışırken neler yapabileceği konusunda kısıtlamalar getirir. Bu dokümanda, işletim sisteminde yapılan değişiklikler ve uygulamanızı yeni sınırlamalara uygun şekilde çalışacak şekilde nasıl güncelleyebileceğiniz açıklanmaktadır.
Genel Bakış
Birçok Android uygulaması ve hizmeti aynı anda çalışabilir. Örneğin, bir kullanıcı bir pencerede oyun oynarken başka bir pencerede web'e göz atabilir ve müzik çalmak için üçüncü bir uygulama kullanabilir. Aynı anda çalışan uygulama sayısı arttıkça sisteme binen yük de artar. Arka planda çalışan ek uygulamalar veya hizmetler, sisteme ek yük bindirir. Bu da kötü bir kullanıcı deneyimine neden olabilir. Örneğin, müzik uygulaması aniden kapanabilir.
Android 8.0, bu tür sorunların olasılığını azaltmak için kullanıcılar doğrudan uygulamayla etkileşimde bulunmadığında uygulamaların yapabileceklerine kısıtlamalar getirir. Uygulamalar iki şekilde kısıtlanır:
Arka Plan Hizmeti Sınırlamaları: Bir uygulama boştayken arka plan hizmetlerini kullanımıyla ilgili sınırlamalar vardır. Bu, kullanıcı tarafından daha belirgin olan ön plan hizmetleri için geçerli değildir.
Yayın sınırlamaları: Uygulamalar, sınırlı istisnalar dışında, dolaylı yayınlara kaydolmak için manifest dosyalarını kullanamaz. Uygulama geliştiriciler, bu yayınlara çalışma zamanında kaydolmayı ve uygunsuz yayınlara ve özellikle uygulamalarını hedefleyen yayınlara kaydolmak için manifest'i kullanmaya devam edebilir.
Çoğu durumda uygulamalar, JobScheduler
işlerini kullanarak bu sınırlamaları aşabilir. Bu yaklaşım, uygulamanın etkin olarak çalışmadığı zamanlarda iş yapmasına olanak tanır ancak sisteme bu işleri kullanıcı deneyimini etkilemeyecek şekilde planlama esnekliği verir. Android 8.0, JobScheduler
'te hizmetleri ve yayın alıcılarını planlanmış işlerle değiştirmeyi kolaylaştıran çeşitli iyileştirmeler sunar. Daha fazla bilgi için İş planlayıcı iyileştirmeleri başlıklı makaleyi inceleyin.
Arka Plan Hizmeti Sınırlamaları
Arka planda çalışan hizmetler cihaz kaynaklarını tüketebilir ve kullanıcı deneyiminin kötüleşmesine neden olabilir. Sistem bu sorunu azaltmak için hizmetlere çeşitli sınırlamalar uygular.
Sistem, ön plan ve arka plan uygulamalarını birbirinden ayırır. (Hizmet sınırlamaları için arka planın tanımı, bellek yönetimi tarafından kullanılan tanımdan farklıdır; bir uygulama, bellek yönetimi açısından arka planda olabilir ancak hizmet başlatma özelliği açısından ön planda olabilir.) Aşağıdakilerden herhangi biri geçerliyse uygulama ön planda kabul edilir:
- Etkinlik başlatılmış veya duraklatılmış olsa bile görünür bir etkinliğe sahip olmalıdır.
- Uygulamada ön plan hizmeti var.
- Başka bir ön plan uygulaması, hizmetlerinden birine bağlanarak veya içerik sağlayıcılarından birini kullanarak uygulamaya bağlıdır. Örneğin, başka bir uygulama aşağıdakilere bağlanırsa uygulama ön plandadır:
- IME
- Duvar kağıdı hizmeti
- Bildirim dinleyici
- Sesli veya kısa mesaj hizmeti
Bu koşullardan hiçbiri doğru değilse uygulamanın arka planda olduğu kabul edilir.
Bir uygulama ön plandayken hem ön plan hem de arka plan hizmetleri oluşturabilir ve bunları özgürce çalıştırabilir. Arka plana geçen bir uygulamanın, hizmet oluşturmasına ve kullanmasına birkaç dakika boyunca izin verilir. Bu sürenin sonunda uygulama beklemede olarak kabul edilir. Bu sırada sistem, uygulamanın hizmetlerinin Service.stopSelf()
yöntemlerini çağırmış gibi uygulamanın arka plan hizmetlerini durdurur.
Belirli durumlarda, arka plan uygulaması birkaç dakika boyunca geçici izin verilenler listesine yerleştirilir. İzin verilenler listesinde yer alan uygulamalar, hizmetler sınırsız olarak başlatabilir ve arka plan hizmetlerinin çalışmasına izin verilir. Bir uygulama, kullanıcı tarafından görülebilen bir görevi yerine getirdiğinde izin verilenler listesine yerleştirilir. Örneğin:
- Yüksek öncelikli bir Firebase Cloud Messaging (FCM) mesajını işleme.
- SMS/MMS mesajı gibi bir yayın alma.
- Bildirimden
PendingIntent
çalıştırma. - VPN uygulaması kendisini ön plana getirmeden önce
VpnService
başlatma
Uygulamanız çoğu durumda arka plan hizmetlerini JobScheduler
işleriyle değiştirebilir.
Örneğin, CoolPhotoApp uygulamasının, ön planda çalışmasa bile kullanıcının arkadaşlarıyla paylaşılan fotoğraflar alıp almadığını kontrol etmesi gerekir. Daha önce uygulama, uygulamanın bulut depolama alanıyla kontrol eden bir arka plan hizmeti kullanıyordu. Geliştirici, Android 8.0'a (API düzeyi 26) geçmek için arka plan hizmetini, düzenli olarak başlatılan, sunucuyu sorgulayan ve ardından kapanan planlı bir işlevle değiştirir.
Android 8.0'dan önce, ön plan hizmeti oluşturmanın genel yolu arka plan hizmeti oluşturmak ve ardından bu hizmeti ön plana taşımaktı.
Android 8.0'da bir sorun vardır. Sistem, arka plan uygulamasının arka plan hizmeti oluşturmasına izin vermez. Bu nedenle Android 8.0, ön planda yeni bir hizmet başlatmak için startForegroundService()
adlı yeni yöntemi kullanıma sunar. Sistem hizmeti oluşturduktan sonra uygulamanın, yeni hizmetin kullanıcı tarafından görülebilen bildirimini göstermek için hizmetin [startForeground()
](/reference/android/app/Service#startForeground(int, android.app.Notification) yöntemini çağırması beş saniye sürer. Uygulama, zaman sınırı içinde startForeground()
çağrısını etmezse sistem hizmeti durdurur ve uygulamanın ANR olduğunu bildirir.
Yayın sınırlamaları
Bir uygulama yayınları almaya kaydolursa uygulamanın alıcısı, yayın her gönderildiğinde kaynak tüketir. Sistem etkinliklerine dayalı yayınları almak için çok fazla uygulama kaydolursa bu durum sorunlara neden olabilir. Bir yayını tetikleyen sistem etkinliği, tüm bu uygulamaların kaynaklarını hızlı bir şekilde tüketmesine neden olarak kullanıcı deneyimini olumsuz etkileyebilir. Bu sorunu azaltmak için Android 7.0 (API seviyesi 24), Arka Planda Optimizasyon bölümünde açıklandığı gibi yayınlara sınırlamalar getirdi. Android 8.0 (API düzeyi 26), bu sınırlamaları daha da katı hale getirir.
- Android 8.0 veya sonraki sürümleri hedefleyen uygulamalar, yayın özellikle ilgili uygulamayla kısıtlanmadığı sürece artık manifest dosyalarında yayın alıcılarını kayıtlı yayınlar için kaydedemez. Yarı açık yayın, bir uygulamadaki belirli bir bileşeni hedeflemeyen bir yayındır. Örneğin,
ACTION_PACKAGE_REPLACED
, tüm uygulamalardaki kayıtlı dinleyicilere gönderilerek cihazdaki bir paketin değiştirildiğini bildirir. Yayın, gizli olduğu için Android 8.0 veya sonraki sürümleri hedefleyen uygulamalarda manifest'e kayıtlı alıcılara yayınlanmaz.ACTION_MY_PACKAGE_REPLACED
da örtülü bir yayındır ancak yalnızca paketi değiştirilen uygulamaya gönderildiği için manifest'e kayıtlı alıcılara teslim edilir. - Uygulamalar, içeriklerinde uygunsuz yayınlara kaydolmaya devam edebilir.
- Uygulamalar, açık veya gizli tüm yayınlar için bir alıcı kaydetmek amacıyla çalışma zamanında
Context.registerReceiver()
kullanabilir. - İmza izni gerektiren yayınlar, cihazdaki tüm uygulamalara değil yalnızca aynı sertifikayla imzalanan uygulamalara gönderildiği için bu kısıtlamadan muaftır.
Çoğu durumda, daha önce dolaylı yayına kayıtlı olan uygulamalar, JobScheduler
işi kullanarak benzer işlevlere sahip olabilir.
Örneğin, bir sosyal fotoğraf uygulamasının zaman zaman verilerini temizlemesi gerekebilir ve bunu cihaz şarj cihazına bağlıyken yapmayı tercih edebilir.
Daha önce uygulama, manifest dosyasında ACTION_POWER_CONNECTED
için bir alıcı kaydediyordu. Uygulama bu yayını aldığında temizlemenin gerekli olup olmadığını kontrol ediyordu. Uygulama, Android 8.0 veya sonraki bir sürüme geçmek için bu alıcıyı manifest dosyasından kaldırır. Bunun yerine uygulama, cihaz boştayken ve şarj olurken çalışan bir temizleme işi planlar.
Taşıma Rehberi
Bu değişiklikler varsayılan olarak yalnızca Android 8.0 (API düzeyi 26) veya sonraki sürümleri hedefleyen uygulamaları etkiler. Ancak kullanıcılar, uygulama 26'dan düşük bir API düzeyini hedefliyorsa bile Ayarlar ekranından herhangi bir uygulama için bu kısıtlamaları etkinleştirebilir. Uygulamanızı yeni sınırlamalara uygun olacak şekilde güncellemeniz gerekebilir.
Uygulamanızın hizmetleri nasıl kullandığını kontrol edin. Uygulamanız, boştayken arka planda çalışan hizmetlere ihtiyaç duyuyorsa bunları değiştirmeniz gerekir. Olası çözümler şunlardır:
- Uygulamanızın arka plandayken ön plan hizmeti oluşturması gerekiyorsa
startService()
yerinestartForegroundService()
yöntemini kullanın. - Hizmet kullanıcı tarafından fark ediliyorsa ön plan hizmeti yapın. Örneğin, ses çalan bir hizmet her zaman ön plan hizmeti olmalıdır.
startService()
yerinestartForegroundService()
yöntemini kullanarak hizmeti oluşturun. - Planlanmış bir iş kullanarak hizmetin işlevini kopyalamanın bir yolunu bulun. Hizmet, kullanıcı tarafından hemen fark edilebilecek bir şey yapmıyorsa genellikle bunun yerine planlanmış bir iş kullanabilirsiniz.
- Arka planda anket yapmak yerine, ağ etkinlikleri gerçekleştiğinde uygulamanızı seçerek uyandırmak için FCM'yi kullanın.
- Arka plan işini, uygulama doğal olarak ön planda olana kadar erteleyin.
Uygulamanızın manifest dosyasında tanımlanan yayın alıcılarını inceleyin. Manifestiniz, etkilenen bir örtülü yayın için alıcı belirtiyorsa bu alıcıyı değiştirmeniz gerekir. Olası çözümler şunlardır:
- Alıcının manifest dosyasında tanımlanması yerine
Context.registerReceiver()
çağrısı yaparak alıcıyı çalışma zamanında oluşturun. - Örtük yayını tetikleyecek koşulu kontrol etmek için planlanmış bir iş kullanın.