Android 8.0 Davranış Değişiklikleri

Android 8.0 (API seviyesi 26), yeni özellikler ve olanakların yanı sıra çeşitli sistem ve API davranış değişiklikleri içerir. Bu dokümanda, uygulamalarınızda anlamanız ve hesaba katmanız gereken bazı önemli değişiklikler vurgulanmaktadır.

Bu değişikliklerin çoğu, hedeflenen Android sürümü ne olursa olsun tüm uygulamaları etkiler. Ancak bazı değişiklikler yalnızca Android 8.0'ı hedefleyen uygulamaları etkilemektedir. Anlaşılırlığı en üst düzeye çıkarmak amacıyla bu sayfa iki bölüme ayrılmıştır: Tüm uygulamalar için değişiklikler ve Android 8.0'ı hedefleyen uygulamalar için değişiklikler.

Tüm uygulamalar için değişiklikler

Bu davranış değişiklikleri, hedefledikleri API düzeyi ne olursa olsun Android 8.0 (API düzeyi 26) platformunda çalıştırılan tüm uygulamalar için geçerlidir. Tüm geliştiriciler, bu değişiklikleri incelemeli ve doğru şekilde desteklemek için uygulamalarında değişiklik yapmalıdır.

Arka planda yürütme sınırları

Android 8.0'ın (API düzeyi 26) pil ömrünü iyileştirmek için yaptığı değişikliklerden biri olarak, uygulamanız etkin bileşen olmadan önbelleğe alındı durumuna girdiğinde sistem, uygulamanın içerdiği uyanık kalma kilitlerini yayınlar.

Ayrıca, sistem, cihaz performansını iyileştirmek için ön planda çalışmayan uygulamaların belirli davranışlarını sınırlar. Özellikle:

  • Arka planda çalışan uygulamaların arka plan hizmetlerine erişim serbestliği konusunda artık sınırlamalar vardır.
  • Uygulamalar çoğu örtülü yayına (yani uygulamaya özel olarak hedeflenmeyen yayınlar) kaydolmak için manifest dosyalarını kullanamaz.

Varsayılan olarak, bu kısıtlamalar yalnızca O. Ancak, uygulama O'yu hedeflememiş olsa bile kullanıcılar, Ayarlar ekranından herhangi bir uygulama için bu kısıtlamaları etkinleştirebilir.

Android 8.0 (API düzeyi 26) belirli yöntemlerde aşağıdaki değişiklikleri de içermektedir:

  • Android 8.0'ı hedefleyen bir uygulama, arka plan hizmetleri oluşturmasına izin verilmediği bir durumda bu yöntemi kullanmaya çalışırsa startService() yöntemi artık bir IllegalStateException gönderir.
  • Yeni Context.startForegroundService() yöntemi, bir ön plan hizmeti başlatır. Sistem, uygulamaların arka plandayken bile Context.startForegroundService() işlevini çağırmasına izin verir. Ancak uygulama, hizmet oluşturulduktan sonraki beş saniye içinde bu hizmetin startForeground() yöntemini çağırmalıdır.

Daha fazla bilgi için Arka Plan Yürütme Sınırları bölümüne bakın.

Android arka planda konum sınırları

Arka plan uygulamaları Android 8.0 çalıştıran bir cihazda kullanıldığında pil, kullanıcı deneyimi ve sistem sağlığını korumak için konum güncellemelerini daha seyrek alır. Bu davranış değişikliği, Google Play Hizmetleri de dahil olmak üzere konum güncellemeleri alan tüm uygulamaları etkiler.

Bu değişiklikler şu API'leri etkilemektedir:

  • Çok Kaynaklı Konum Sağlayıcı (FLP)
  • Coğrafi sınır çizme
  • GNSS Ölçümleri
  • Konum Yöneticisi
  • Kablosuz Ağ Yöneticisi

Uygulamanızın beklendiği gibi çalıştığından emin olmak için aşağıdaki adımları tamamlayın:

  • Uygulamanızın mantığını inceleyin ve en yeni konum API'lerini kullandığınızdan emin olun.
  • Uygulamanızın, her kullanım alanında beklediğiniz davranışı sergileyip sergilemediğini test edin.
  • Kullanıcının mevcut konumuna bağlı olan kullanım alanlarını yönetmek için Çok Kaynaklı Konum Sağlayıcı'yı (FLP) veya coğrafi sınır çizmeyi kullanmayı düşünün.

Bu değişiklikler hakkında daha fazla bilgi için Arka Planda Konum Sınırları bölümüne bakın.

Uygulama kısayolları

Android 8.0 (API düzeyi 26), uygulama kısayollarında aşağıdaki değişiklikleri içerir:

  • Artık özel ve dolaylı bir yayın olduğundan com.android.launcher.action.INSTALL_SHORTCUT yayınının uygulamanız üzerinde bir etkisi yoktur. Bunun yerine, ShortcutManager sınıfındaki requestPinShortcut() yöntemini kullanarak bir uygulama kısayolu oluşturmanız gerekir.
  • ACTION_CREATE_SHORTCUT amacı artık ShortcutManager sınıfını kullanarak yönettiğiniz uygulama kısayolları oluşturabilir. Bu amaç, ShortcutManager ile etkileşime girmeyen eski başlatıcı kısayolları da oluşturabilir. Daha önce, bu amaç yalnızca eski başlatıcı kısayollarını oluşturabiliyordu.
  • requestPinShortcut() kullanılarak oluşturulan kısayollar ve ACTION_CREATE_SHORTCUT amacını işleyen bir etkinlikte oluşturulan kısayollar artık tam kapsamlı uygulama kısayolları oluyor. Sonuç olarak, uygulamalar artık bunları ShortcutManager içindeki yöntemleri kullanarak güncelleyebilir.
  • Eski kısayollar, Android'in önceki sürümlerindeki işlevlerini korur, ancak bunları uygulamanızda manuel olarak uygulama kısayollarına dönüştürmeniz gerekir.

Uygulama kısayollarında yapılan değişiklikler hakkında daha fazla bilgi edinmek için Kısayolları ve Widget'ları Sabitleme özelliği kılavuzuna bakın.

Yerel ayarlar ve uluslararasılaştırma

Android 7.0 (API düzeyi 24), varsayılan bir Kategori Yerel Ayarı belirtebilme kavramını ortaya çıkarmıştı, ancak bazı API'ler, bunun yerine varsayılan DISPLAY kategorisi Yerel Ayarını kullanmaları gerekirken, bağımsız değişken olmadan genel Locale.getDefault() yöntemini kullanmaya devam etti. Android 8.0'da (API düzeyi 26) aşağıdaki yöntemler artık Locale.getDefault() yerine Locale.getDefault(Category.DISPLAY) kullanıyor:

Locale bağımsız değişkeni için belirtilen displayScript değeri kullanılamadığında Locale.getDisplayScript(Locale), Locale.getDefault() değerine de geri döner.

Yerel ayarlar ve uluslararasılaştırmayla ilgili diğer değişiklikler aşağıda belirtilmiştir:

  • Currency.getDisplayName(null) çağrıldığında, belgelenen davranışla eşleşen bir NullPointerException döndürülür.
  • Saat dilimi adı ayrıştırma işlemi değişti. Daha önce Android cihazlar, tarih saatlerini ayrıştırmak amacıyla kullanılan saat dilimi adlarını önbelleğe almak için başlatma zamanında örneklenen sistem saati değerini kullanıyordu. Bunun sonucunda, sistem saati başlatma sırasında veya daha nadir görülen diğer durumlarda yanlışsa ayrıştırma işlemi olumsuz etkilenebilir.

    Şimdi ise ayrıştırma mantığı, saat dilimi adlarını ayrıştırırken ICU'yu ve mevcut sistem saat değerini kullanır. Bu değişiklik daha doğru sonuçlar sağlar. Bu da uygulamanızda SimpleDateFormat gibi sınıfların kullanıldığı önceki Android sürümlerinden farklı olabilir.

  • Android 8.0 (API düzeyi 26), ICU sürümünü sürüm 58 olarak günceller.

Uyarı pencereleri

Bir uygulama SYSTEM_ALERT_WINDOW iznini kullanıyorsa ve uyarı pencerelerini diğer uygulamaların ve sistem pencerelerinin üzerinde görüntülemeye çalışmak için aşağıdaki pencere türlerinden birini kullanıyorsa:

...bu pencereler her zaman TYPE_APPLICATION_OVERLAY pencere türünü kullanan pencerelerin altında görünür. Android 8.0 (API düzeyi 26) sürümünü hedefleyen uygulama, uyarı pencereleri görüntülemek için TYPE_APPLICATION_OVERLAY pencere türünü kullanır.

Daha fazla bilgi için Android 8.0'ı hedefleyen uygulamaların davranış değişikliklerindeki Uyarı pencereleri için yaygın pencere türleri bölümüne bakın.

Giriş ve gezinme

ChromeOS'te ve tabletler gibi diğer büyük form faktörlerinde Android uygulamalarının ortaya çıkmasıyla birlikte, Android uygulamalarında klavyeyle gezinmenin yeniden yükselişe geçtiğini görüyoruz. Android 8.0'da (API düzeyi 26) klavyeyi navigasyon giriş cihazı olarak kullanma konusunu yeniden ele aldık. Bu da ok ve sekme tabanlı gezinme için daha güvenilir, öngörülebilir bir model ortaya çıkardı.

Özellikle öğe odağı davranışında aşağıdaki değişiklikleri yaptık:

  • Bir View nesnesi (ön planı veya arka planı çekilebilir) için odak durumu rengi tanımlamadıysanız çerçeve artık View için varsayılan odak vurgulama rengi ayarlıyor. Odak vurgulama özelliği, etkinliğin temasına dayalı olarak dalga çekilebilir bir öğedir.

    Bir View nesnesinin odağı aldığında bu varsayılan vurgulamayı kullanmasını istemiyorsanız View öğesini içeren düzen XML dosyasında android:defaultFocusHighlightEnabled özelliğini false olarak ayarlayın veya uygulamanızın kullanıcı arayüzü mantığında false öğesini setDefaultFocusHighlightEnabled() öğesine geçirin.

  • Klavye girişinin kullanıcı arayüzü öğesinin odağını nasıl etkilediğini test etmek için Çizim > Düzen sınırlarını göster geliştirici seçeneğini etkinleştirebilirsiniz. Android 8.0'da bu seçenek, geçerli olarak odağın bulunduğu öğenin üzerinde "X" simgesini gösterir.

Ayrıca Android 8.0'daki tüm araç çubuğu öğeleri, otomatik olarak klavyeyle gezinme kümeleridir. Böylece kullanıcıların her araç çubuğuna bir bütün olarak girip çıkması kolaylaşır.

Uygulamanızda klavyeyle gezinme desteğinin nasıl geliştirileceği hakkında daha fazla bilgi edinmek için Klavyede Gezinmeyi Destekleme kılavuzunu okuyun.

Web formunu otomatik doldurma

Artık Android Otomatik Doldurma Çerçeve, otomatik doldurma işlevi için dahili destek sağladığından Android 8.0 (API düzeyi 26) çalıştıran cihazlarda yüklü uygulamalarda WebView nesneleriyle ilgili olarak aşağıdaki yöntemler değiştirilmiştir:

WebSettings
  • getSaveFormData() yöntemi artık false değerini döndürüyor. Daha önce bu yöntem bunun yerine true döndürüyordu.
  • setSaveFormData() numaralı telefonu çağırmanın artık herhangi bir etkisi yok.
WebViewDatabase
  • clearFormData() numaralı telefonu çağırmanın artık herhangi bir etkisi yok.
  • hasFormData() yöntemi artık false değerini döndürüyor. Daha önce bu yöntem, form veri içerdiğinde true değerini döndürüyordu.

Erişilebilirlik

Android 8.0 (API düzeyi 26), erişilebilirlikle ilgili aşağıdaki değişiklikleri içerir:

  • Erişilebilirlik çerçevesi artık tüm iki kez dokunma hareketlerini ACTION_CLICK işlemlerine dönüştürüyor. Bu değişiklik, TalkBack'in diğer erişilebilirlik hizmetlerine daha çok benzemesini sağlar.

    Uygulamanızın View nesneleri özel dokunma işleme kullanıyorsa bunların hâlâ TalkBack ile çalıştığını doğrulamanız gerekir. Yalnızca View nesnelerinizin kullandığı tıklama işleyiciyi kaydetmeniz gerekebilir. TalkBack bu View nesnelerde gerçekleştirilen hareketleri hâlâ tanımıyorsa performAccessibilityAction() özelliğini geçersiz kılın.

  • Erişilebilirlik hizmetleri artık uygulamanızın TextView nesneleri içindeki tüm ClickableSpan örneklerinin farkındadır.

Uygulamanızı nasıl daha erişilebilir hale getirebileceğiniz hakkında daha fazla bilgi edinmek için Erişilebilirlik konusuna bakın.

Ağ ve HTTP(S) bağlantısı

Android 8.0 (API düzeyi 26), ağ iletişimi ve HTTP(S) bağlantısında aşağıdaki davranış değişikliklerini içerir:

  • Gövdesi olmayan OPTIONS isteklerin Content-Length: 0 başlığı var. Önceden Content-Length başlığı yoktu.
  • HttpURLConnection, ana makine veya yetkili adından sonra eğik çizgi ekleyerek boş yollar içeren URL'leri normalleştirir. Örneğin, http://example.com değerini http://example.com/ olarak dönüştürür.
  • ProxySelector.setDefault() aracılığıyla ayarlanan özel bir proxy seçici, yalnızca istenen bir URL'nin adresini (şema, ana makine ve bağlantı noktası) hedefler. Sonuç olarak, proxy seçimi yalnızca bu değerlere göre yapılabilir. Özel proxy seçiciye iletilen bir URL, istenen URL'nin yolunu, sorgu parametrelerini veya parçalarını içermez.
  • URI'ler boş etiketler içeremez.

    Önceden platform, ana makine adlarında boş etiketlerin kabul edilmesi için bir geçici çözümü destekliyordu. Bu, URI'lerin yasa dışı bir kullanımıdır. Bu geçici çözüm, eski libcore sürümleriyle uyumluluk içindi. API'yi yanlış kullanan geliştiriciler, şu ADB mesajıyla karşılaşırlar: "URI example.com'un ana makine adında boş etiketler var. Bu hatalı biçimlendirilmiş ve gelecekteki Android sürümlerinde kabul edilmeyecektir. Android 8.0 bu geçici çözümü kaldırır. Sistem, bozuk URI'lar için null değerini döndürür.

  • Android 8.0’ın HttpsURLConnection uygulaması, güvenli olmayan TLS/SSL protokol sürümü yedeği gerçekleştirmez.
  • Tünel HTTP(S) bağlantılarının işlenmesi aşağıdaki gibi değiştirilmiştir:
    • Bağlantı üzerinden HTTPS bağlantısı üzerinden tünel oluştururken sistem, bu bilgileri bir ara sunucuya gönderirken bağlantı noktası numarasını (:443) Ana Makine satırına doğru şekilde yerleştirir. Önceden bağlantı noktası numarası yalnızca CONNECT satırında bulunuyordu.
    • Sistem artık tünelli bir istekten kullanıcı aracısı ve proxy yetkilendirme üst bilgilerini proxy sunucuya göndermez.

      Sistem artık tüneli ayarlarken tünelli Http(s)URLConnection'da proxy'ye proxy yetkilendirmesi üst bilgisi göndermez. Bunun yerine, sistem bir proxy yetkilendirme üst bilgisi oluşturur ve bu proxy ilk isteğe yanıt olarak HTTP 407 gönderdiğinde proxy'ye gönderir.

      Benzer şekilde, sistem artık kullanıcı aracısı üst bilgisini tünelli istekten tüneli ayarlayan proxy isteğine kopyalamaz. Bunun yerine, kitaplık bu istek için bir user-agent başlığı oluşturur.

  • Daha önce yürütülen connect() yöntemi başarısız olursa send(java.net.DatagramPacket) yöntemi bir SocketException bildirir.
    • Dahili bir hata varsa DatagramSocket.connect() bir pendingSocketException ayarlar. Android 8.0'dan önce, bir send() çağrısı başarılı olsa bile bir sonraki recv() çağrısı bir SocketException oluşturuyordu. Tutarlılık için her iki çağrı da artık bir SocketException döndürür.
  • InetAddress.isReachable(), TCP Yankı protokolüne geri dönmeden önce ICMP'yi dener.
    • 7. bağlantı noktasını (TCP Echo) engelleyen bazı ana makineler (ör. google.com), ICMP Echo protokolünü kabul etmeleri durumunda artık erişilebilir hale gelebilir.
    • Gerçekten erişilemeyen ana makineler için bu değişiklik, çağrı geri dönmeden önce harcanan sürenin iki katına çıktığı anlamına gelir.

Bluetooth

Android 8.0 (API düzeyi 26), ScanRecord.getBytes() yönteminin aldığı verilerin uzunluğunda aşağıdaki değişiklikleri yapar:

  • getBytes() yöntemi, alınan bayt sayısıyla ilgili herhangi bir varsayımda bulunmaz. Bu nedenle, uygulamalar döndürülen minimum veya maksimum bayt sayısını temel almamalıdır. Bunun yerine, elde edilen dizinin uzunluğunu değerlendirmelidirler.
  • Bluetooth 5 uyumlu cihazlar, önceki maksimum sınır olan yaklaşık 60 baytı aşan veri uzunluğu döndürebilir.
  • Uzak cihaz da tarama yanıtı sağlamazsa 60 bayttan daha az sonuç döndürülebilir.

Sorunsuz Bağlantı

Android 8.0 (API düzeyi 26), en iyi kullanıcı deneyimini sunan kablosuz ağı seçmeyi kolaylaştırmak için Kablosuz Ayarları'nda çeşitli iyileştirmeler yapar. Belirli değişiklikler şunlardır:

  • Kararlılık ve güvenilirlik iyileştirmeleri.
  • Daha sezgisel bir kullanıcı arayüzü.
  • Tek bir birleştirilmiş Kablosuz Tercihleri menüsü.
  • Uyumlu cihazlarda, yakınınızda yüksek kaliteli kayıtlı bir ağ olduğunda kablosuz bağlantının otomatik olarak etkinleştirilmesi.

Güvenlik

Android 8.0, güvenlikle ilgili aşağıdaki değişiklikleri içerir:

  • Platform artık SSLv3'ü desteklememektedir.
  • TLS protokolü sürümü iletişimini yanlış uygulayan bir sunucuyla HTTPS bağlantısı kurulurken HttpsURLConnection, artık önceki TLS protokolü sürümlerine geri dönüp yeniden deneme gibi geçici çözümü denemez.
  • Android 8.0 (API düzeyi 26), tüm uygulamalara Güvenli Bilişim (SECCOMP) filtresi uygular. İzin verilen syscall'ların listesi, biyonik yolla maruz kalanlarla sınırlıdır. Geriye dönük uyumluluk için sağlanmış başka birçok sistem çağrısı olsa da bunların kullanılmamasını öneririz.
  • Uygulamanızın WebView nesneleri artık çoklu işlem modunda çalışıyor. Web içeriği, gelişmiş güvenlik için kapsayıcı uygulamanın işleminden ayrı ve izole bir işlemde işlenir.
  • Artık APK'ların adları -1 veya -2 ile biten dizinlerde bulunduğunu varsayamazsınız. Uygulamalar, dizini almak için sourceDir kullanmalı ve doğrudan dizin biçimine bağlı olmamalıdır.
  • Yerel kitaplıkların kullanımıyla ilgili güvenlik geliştirmeleri hakkında bilgi edinmek için Yerel Kitaplıklar bölümüne bakın.

Buna ek olarak, Android 8.0 (API düzeyi 26), bilinmeyen kaynaklardan bilinmeyen uygulamaların yüklenmesiyle ilgili olarak aşağıdaki değişiklikleri yapacaktır:

Bilinmeyen uygulamaların yüklenmesiyle ilgili ek ayrıntılar için Bilinmeyen Uygulama Yükleme İzinleri kılavuzuna bakın.

Uygulamanızı daha güvenli hale getirmeyle ilgili ek yönergeler için Android Geliştiricileri için Güvenlik sayfasına göz atın.

Gizlilik

Android 8.0 (API düzeyi 26), platformda gizlilikle ilgili aşağıdaki değişiklikleri yapar.

  • Platform, tanımlayıcıları artık farklı bir şekilde işlemektedir.
    • Android 8.0 (API düzeyi 26) sürümüne (API düzeyi 26) OTA sürümünden önce yüklenen uygulamalar için ANDROID_ID değeri, kaldırılıp OTA'dan sonra yeniden yüklenmediği sürece aynı kalır. Geliştiriciler, OTA'dan sonra kaldırma işlemleri genelinde değerleri korumak için Anahtar/Değer Yedekleme yöntemini kullanarak eski ve yeni değerleri ilişkilendirebilirler.
    • Android 8.0 çalıştıran bir cihaza yüklenen uygulamalar için ANDROID_ID değeri artık hem uygulama imzalama anahtarı hem de kullanıcı başına kapsama alınıyor. Her uygulama imzalama anahtarı, kullanıcı ve cihaz kombinasyonu için ANDROID_ID değeri benzersizdir. Sonuç olarak, aynı cihazda çalışan farklı imzalama anahtarları olan uygulamalar artık aynı Android kimliğini görmez (aynı kullanıcı için bile).
    • İmzalama anahtarı aynı olduğu (ve uygulama, Android 8.0'ın OTA sürümünden önce yüklenmediği) sürece paket kaldırma veya yeniden yükleme işleminde ANDROID_ID değeri değişmez.
    • Sistem güncellemesi paket imzalama anahtarının değişmesine neden olsa bile ANDROID_ID değeri değişmez.
    • Google Play Hizmetleri ve Reklam Kimliği ile gönderilen cihazlarda Reklam Kimliği kullanmanız gerekir. Uygulamalardan para kazanmak için kullanılan basit ve standart bir sistem olan Reklam Kimliği, reklamcılık için kullanılan benzersiz ve kullanıcı tarafından sıfırlanabilen bir kimliktir. Google Play Hizmetleri tarafından sağlanır.

      Diğer cihaz üreticileri ANDROID_ID sağlamaya devam etmelidir.

  • net.hostname sistem özelliğinin sorgulanması boş bir sonuç üretir.

Yakalanmayan istisnaları günlüğe kaydetme

Bir uygulama, varsayılan Thread.UncaughtExceptionHandler öğesine çağrı yapmayan bir Thread.UncaughtExceptionHandler yüklerse yakalanmamış bir istisna oluştuğunda sistem uygulamayı sonlandırmaz. Android 8.0'dan (API düzeyi 26) başlayarak sistem, istisna yığını izlemeyi bu durumda günlüğe kaydeder. Platformun önceki sürümlerinde sistem, istisna yığını izlemeyi kaydetmezdi.

Özel Thread.UncaughtExceptionHandler uygulamalarının her zaman varsayılan işleyiciye çağrıda bulunmasını öneririz. Bu öneriyi uygulayan uygulamalar Android 8.0'daki değişiklikten etkilenmez.

findViewById() imza değişikliği

findViewById() yönteminin tüm örnekleri artık View yerine <T extends View> T döndürüyor. Bu değişiklik aşağıdaki sonuçlara neden olacaktır:

  • Bu durum, mevcut kodun artık belirsiz bir dönüş türüne sahip olmasına neden olabilir. Örneğin, findViewById() öğesine yapılan bir çağrının sonucunu alan someMethod(View) ve someMethod(TextView) varsa.
  • Java 8 kaynak dili kullanıldığında bu, döndürme türü kısıtlanmamışsa (örneğin, assertNotNull(findViewById(...)).someViewMethod())) View öğesine açık yayın gerektirir.
  • Nihai olmayan findViewById() yöntemlerinin (örneğin, Activity.findViewById()) geçersiz kılınması için dönüş türlerinin güncellenmesi gerekir.

Kişi sağlayıcı kullanım istatistiklerinde değişiklik

Android'in önceki sürümlerinde, Kişi Sağlayıcı bileşeni, geliştiricilerin her bir kişi için kullanım verilerini almasına olanak tanır. Bu kullanım verileri, kişiyle ilişkilendirilmiş her e-posta adresi ve telefon numarasıyla ilgili bilgileri (kişiyle kaç kez ve en son ne zaman iletişime geçildiği dahil) açığa çıkarır. READ_CONTACTS iznini isteyen uygulamalar bu verileri okuyabilir.

Uygulamalar, READ_CONTACTS izni isterlerse bu verileri okumaya devam edebilir. Android 8.0 (API düzeyi 26) ve sonraki sürümlerde, kullanım verilerine yönelik sorgular tam değerler yerine yaklaşık değerleri döndürür. Android sistemi tam değerleri dahili olarak koruduğundan bu değişiklik otomatik tamamlama API'sini etkilemez.

Bu davranış değişikliği aşağıdaki sorgu parametrelerini etkiler:

Tahsilat işleme

AbstractCollection.removeAll() ve AbstractCollection.retainAll() artık her zaman bir NullPointerException atıyor; eskiden, koleksiyon boşken NullPointerException atılmıyordu. Bu değişiklik, davranışı dokümanlarla tutarlı hâle getirir.

Android Enterprise

Android 8.0 (API düzeyi 26), cihaz politikası denetleyiciler (DPC'ler) dahil olmak üzere kurumsal uygulamalar için bazı API'lerin ve özelliklerin davranışını değiştirir. Söz konusu değişiklikler şunlardır:

  • Uygulamaların, tümüyle yönetilen cihazlarda iş profillerini desteklemesine yardımcı olacak yeni davranışlar.
  • Cihaz ve sistem bütünlüğünü artırmak için sistem güncellemesi işleme, uygulama doğrulama ve kimlik doğrulamada yapılan değişiklikler.
  • Temel hazırlık, bildirimler, Son Kullanılanlar ekranı ve her zaman açık VPN için kullanıcı deneyiminde iyileştirmeler.

Android 8.0'daki (API düzeyi 26) tüm kurumsal değişiklikleri görmek ve bu değişikliklerin uygulamanızı nasıl etkileyebileceğini öğrenmek için Kurumsal Android makalesini okuyun.

Android 8.0'ı hedefleyen uygulamalar

Bu davranış değişiklikleri yalnızca Android 8.0 (API düzeyi 26) veya sonraki sürümleri hedefleyen uygulamalar için geçerlidir. Android 8.0'a göre derlenen veya targetSdkVersion özelliğini Android 8.0 ya da sonraki bir sürüme ayarlayan uygulamalar, uygun olduğu durumlarda bu davranışları doğru bir şekilde desteklemek için uygulamalarını değiştirmelidir.

Uyarı pencereleri

SYSTEM_ALERT_WINDOW iznini kullanan uygulamalar, uyarı pencerelerini diğer uygulamaların ve sistem pencerelerinin üstünde görüntülemek için artık aşağıdaki pencere türlerini kullanamaz:

Bunun yerine, uygulamalar TYPE_APPLICATION_OVERLAY adlı yeni bir pencere türü kullanmalıdır.

Uygulamanızla ilgili uyarı pencereleri görüntülemek için TYPE_APPLICATION_OVERLAY pencere türünü kullanırken yeni pencere türünün aşağıdaki özelliklerini göz önünde bulundurun:

  • Bir uygulamanın uyarı pencereleri her zaman durum çubuğu ve IME'ler gibi kritik sistem pencerelerinin altında görünür.
  • Sistem, ekran sunumunu iyileştirmek için TYPE_APPLICATION_OVERLAY pencere türünü kullanan pencereleri taşıyabilir veya yeniden boyutlandırabilir.
  • Kullanıcılar bildirim gölgesini açarak bir uygulamanın, TYPE_APPLICATION_OVERLAY pencere türünü kullanarak gösterilen uyarı pencerelerini görüntülemesini engelleyen ayarlara erişebilir.

İçerik değişikliği bildirimleri

Android 8.0 (API düzeyi 26), Android 8.0'ı hedefleyen uygulamalar için ContentResolver.notifyChange() ve registerContentObserver(Uri, boolean, ContentObserver) davranışını değiştirir.

Bu API'ler artık tüm Uris'te yetkili için geçerli bir ContentProvider tanımlanmasını gerektiriyor. İlgili izinlere sahip geçerli bir ContentProvider tanımlamak, uygulamanızı kötü amaçlı uygulamalardan gelen içerik değişikliklerine karşı korumaya ve gizli olabilecek verileri kötü amaçlı uygulamalara sızdırmanızı önlemeye yardımcı olur.

Odağı göster

Artık varsayılan olarak tıklanabilir View nesnelerine de odaklanılabilir. Bir View nesnesinin tıklanabilir ancak odaklanılabilir olmamasını istiyorsanız View öğesini içeren düzen XML dosyasında android:focusable özelliğini false olarak ayarlayın veya uygulamanızın kullanıcı arayüzü mantığında false öğesini setFocusable() öğesine geçirin.

Tarayıcı algılamada kullanıcı aracısı eşleşmesi

Android 8.0 (API düzeyi 26) ve sonraki sürümler, OPR derleme tanımlayıcısı dizesini içerir. Bazı kalıp eşleşmeleri, tarayıcı algılama mantığının Opera olmayan tarayıcıyı yanlış tanımlamasına neden olabilir. Böyle bir kalıp eşleşmesi örneği şu şekilde olabilir:

if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}

Bu tür bir yanlış tanımlamadan kaynaklanan sorunları önlemek için Opera tarayıcısında kalıp eşleşmesi olarak OPR dışında bir dize kullanın.

Güvenlik

Aşağıdaki değişiklikler Android 8.0'da (API düzeyi 26) güvenliği etkiler:

  • Uygulamanızın ağ güvenliği yapılandırması, düz metin trafiğinin desteklenmesini devre dışı bırakırsa uygulamanızın WebView nesneleri HTTP üzerinden web sitelerine erişemez. Bunun yerine her WebView nesnesi HTTPS kullanmalıdır.
  • Bilinmeyen kaynaklara izin ver sistem ayarı kaldırıldı. Bu ayar yerine Bilinmeyen uygulamaları yükleme izni, bilinmeyen kaynaklardan gelen bilinmeyen uygulama yüklemelerini yönetir. Bu yeni izin hakkında daha fazla bilgi edinmek için Bilinmeyen Uygulama Yükleme İzinleri kılavuzuna bakın.

Uygulamanızı daha güvenli hale getirmeyle ilgili ek yönergeler için Android Geliştiricileri için Güvenlik sayfasına göz atın.

Hesaba erişim ve bulunabilirlik

Android 8.0'da (API düzeyi 26) uygulamalar, kullanıcı hesaplarına artık kimlik doğrulayanın sahip olmadığı veya kullanıcı bu erişime izin vermediği sürece kullanıcı hesaplarına erişim elde edemez. GET_ACCOUNTS izni artık yeterli değildir. Bir hesaba erişim izni verilmesi için uygulamaların AccountManager.newChooseAccountIntent() veya kimlik doğrulayıcıya özel bir yöntem kullanması gerekir. Uygulamalar, hesaplara erişim elde ettikten sonra bunlara erişmek için AccountManager.getAccounts() numaralı telefonu arayabilir.

Android 8.0 LOGIN_ACCOUNTS_CHANGED_ACTION için desteği sonlandırıyor. Uygulamalar, çalışma zamanında hesaplarla ilgili güncellemeler almak için addOnAccountsUpdatedListener() kullanmalıdır.

Hesap erişimi ve bulunabilirlik için eklenen yeni API'ler ve yöntemler hakkında bilgi edinmek üzere bu dokümanın Yeni API'ler bölümündeki Hesap Erişimi ve Bulunabilirlik bölümüne bakın.

Gizlilik

Aşağıdaki değişiklikler, Android 8.0'da (API düzeyi 26) gizliliği etkiler.

  • Platformdaki gizliliği iyileştiren bir değişiklik olan net.dns1, net.dns2, net.dns3 ve net.dns4 sistem özellikleri artık kullanılamıyor.
  • ACCESS_NETWORK_STATE iznine sahip uygulamalar, DNS sunucuları gibi ağ iletişimi bilgilerini almak için NetworkRequest veya NetworkCallback nesnesi kaydedebilir. Bu sınıflar Android 5.0 (API düzeyi 21) ve sonraki sürümlerde mevcuttur.
  • Build.SERIAL desteği sonlandırıldı. Donanım seri numarasını bilmesi gereken uygulamalar, bunun yerine READ_PHONE_STATE iznini gerektiren yeni Build.getSerial() yöntemini kullanmalıdır.
  • LauncherApps API artık iş profili uygulamalarının birincil profil hakkında bilgi almasına izin vermemektedir. Kullanıcı bir iş profilindeyken LauncherApps API, aynı profil grubu içindeki diğer profillerde hiçbir uygulama yüklü değilmiş gibi davranır. Daha önce olduğu gibi, alakasız profillere erişme girişimleri, SecurityExceptions'a neden oluyor.

İzinler

Android 8.0'dan (API düzeyi 26) önce, bir uygulama çalışma zamanında izin istemiş ve izin verilmişse sistem, uygulamaya aynı izin grubuna ait olan ve manifest'e kaydedilmiş diğer izinleri de hatalı bir şekilde vermişti.

Android 8.0'ı hedefleyen uygulamalar için bu davranış düzeltilmiştir. Uygulamaya yalnızca açıkça istediği izinler verildi. Bununla birlikte, kullanıcı uygulamaya bir izin verdiğinde, söz konusu izin grubunda yer alan sonraki tüm izin istekleri otomatik olarak kabul edilir.

Örneğin, bir uygulamanın manifest dosyasında hem READ_EXTERNAL_STORAGE hem de WRITE_EXTERNAL_STORAGE listesini listelediğini varsayalım. Uygulama READ_EXTERNAL_STORAGE isteğinde bulunuyor ve kullanıcı buna izin veriyor. Uygulama, API düzeyi 25 veya altını hedefliyorsa sistem, aynı STORAGE izin grubuna ait olduğu ve aynı zamanda manifest'e de kayıtlı olduğu için WRITE_EXTERNAL_STORAGE iznini de verir. Uygulama Android 8.0'ı (API düzeyi 26) hedefliyorsa sistem o anda yalnızca READ_EXTERNAL_STORAGE izni verir. Ancak, uygulama daha sonra WRITE_EXTERNAL_STORAGE isteğinde bulunursa sistem kullanıcıya sormadan bu ayrıcalığı hemen verir.

Medya

  • Çerçeve kendi başına otomatik ses kısma işlemini gerçekleştirebilir. Bu durumda, başka bir uygulama AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ile odaklanma isteğinde bulunduğunda odaklanılan uygulama ses düzeyini düşürür, ancak genellikle onAudioFocusChange() geri çağırması almaz ve ses odağını kaybetmez. Sesi kısmak yerine duraklatılması gereken uygulamalarda bu davranışı geçersiz kılmak için yeni API'ler kullanıma sunulmuştur.
  • Kullanıcı telefon araması yaptığında etkin medya akışları arama süresince sessize alınır.
  • Sesle ilgili tüm API'ler, ses çalma kullanım alanını tanımlamak için ses akışı türleri yerine AudioAttributes kullanmalıdır. Ses yayını türlerini yalnızca ses kontrolleri için kullanmaya devam edin. Akış türlerinin diğer kullanımları (örneğin, kullanımdan kaldırılan AudioTrack oluşturucunun streamType bağımsız değişkeni) çalışmaya devam eder ancak sistem bunu bir hata olarak günlüğe kaydeder.
  • AudioTrack kullanılırken uygulama yeterince büyük bir ses arabelleği isterse çerçeve, varsa derin arabellek çıkışını kullanmaya çalışır.
  • Android 8.0'da (API düzeyi 26) medya düğmesi etkinliklerinin işlenmesi farklıdır:
    1. Bir kullanıcı arayüzü etkinliğindeki medya düğmelerinin işlenmesi değişmedi: Ön plan etkinlikleri, medya düğmesi etkinliklerinin işlenmesinde öncelikli olmaya devam ediyor.
    2. Ön plan etkinliği medya düğmesi etkinliğini gerçekleştirmiyorsa sistem, etkinliği yerel olarak en son ses çalan uygulamaya yönlendirir. Bir medya oturumunun etkin durumu, işaretleri ve oynatma durumu, medya düğmesi etkinliklerini alacak uygulama belirlenirken dikkate alınmaz.
    3. Uygulamanın medya oturumu serbest bırakıldıysa sistem, medya düğmesi etkinliğini uygulamanın MediaButtonReceiver öğesine (varsa) gönderir.
    4. Sistem, diğer her durumda medya düğmesi etkinliğini siler.

Yerel kitaplık

Android 8.0'ı (API düzeyi 26) hedefleyen uygulamalarda, hem yazılabilir hem de yürütülebilir yükleme segmenti içeren yerel kitaplıklar artık yüklenmez. Bazı uygulamalar yanlış yükleme segmentlerine sahip yerel kitaplıkları varsa bu değişiklik nedeniyle çalışmayı durdurabilir. Bu, güvenliği güçlendiren bir önlemdir.

Daha fazla bilgi için Yazılabilir ve Yürütülebilir Segmentler konusuna bakın.

Bağlayıcı değişiklikleri, bir uygulamanın hedeflediği API düzeyine bağlıdır. Hedeflenen API düzeyinde bir bağlayıcı değişikliği varsa uygulama, kitaplığı yükleyemez. Bağlayıcı değişikliğinin gerçekleştiği API düzeyinden daha düşük bir API düzeyini hedefliyorsanız logcat bir uyarı gösterir.

Tahsilat işleme

Android 8.0'da (API düzeyi 26), Collections.sort(), List.sort() uygulamasının üzerine uygulanır. Bunun tam tersi, Android 7.x (API düzeyleri 24 ve 25) sürümünde geçerliydi: Varsayılan List.sort() uygulaması Collections.sort() olarak adlandırılır.

Bu değişiklik, Collections.sort() ürününün optimize edilmiş List.sort() uygulamalarından yararlanmasına olanak tanır ancak aşağıdaki kısıtlamaları içerir:

  • List.sort() uygulamaları, sonsuz yinelemeden dolayı yığın taşmasına neden olacağından Collections.sort() yöntemini çağırmamalıdır. Bunun yerine, List uygulamanızda varsayılan davranışı istiyorsanız sort() geçersiz kılınmamalıdır.

    Bir üst sınıf sort() öğesini uygunsuz bir şekilde uygularsa List.toArray(), Arrays.sort() ve ListIterator.set() üzerine kurulu bir uygulama ile List.sort() öğesinin geçersiz kılınması genellikle sorun olmaz. Örnek:

    @Override
    public void sort(Comparator<? super E> c) {
      Object[] elements = toArray();
      Arrays.sort(elements, c);
      ListIterator<E> iterator = (ListIterator<Object>) listIterator();
      for (Object element : elements) {
        iterator.next();
        iterator.set((E) element);
      }
    }
    

    Çoğu durumda, API düzeyine bağlı olarak farklı varsayılan uygulamalara yetki veren bir uygulamayla List.sort() öğesini geçersiz kılabilirsiniz. Örnek:

    @Override
    public void sort(Comparator<? super E> comparator) {
      if (Build.VERSION.SDK_INT <= 25) {
        Collections.sort(this);
      } else {
        super.sort(comparator);
      }
    }
    

    Bunu yalnızca bir sort() yönteminin tüm API düzeylerinde kullanılabilir olmasını istediğiniz için yapıyorsanız sort() yöntemini geçersiz kılmak yerine yönteme sortCompat() gibi benzersiz bir ad vermeyi düşünebilirsiniz.

  • Collections.sort(), artık sort() çağrısı yapan Liste uygulamalarında yapısal bir değişiklik olarak sayılıyor. Örneğin, platformun Android 8.0'dan (API düzeyi 26) önceki sürümlerinde ArrayList yineleme ve iterasyonun ortasında sort() çağrısı yapıldığında sıralama List.sort() çağrısı yapılarak yapılsaydı bu işlem ConcurrentModificationException sonucunu döndürür. Collections.sort() istisna vermedi.

    Bu değişiklik, platform davranışını daha tutarlı hale getirir: Artık her iki yaklaşım da ConcurrentModificationException ile sonuçlanıyor.

Sınıf yükleme davranışı

Android 8.0 (API düzeyi 26), sınıf yükleyicilerin yeni sınıflar yüklerken çalışma zamanı varsayımlarını bozmadığından emin olur. Bu kontroller, sınıfa Java'dan (forName() kaynağından), Dalvik bayt kodundan veya JNI'den başvurulmasından bağımsız olarak gerçekleştirilir. Platform, Java'dan loadClass() yöntemine yapılan doğrudan çağrıları engellemez ve bu tür çağrıların sonuçlarını kontrol etmez. Bu davranış, düzgün çalışan sınıf yükleyicilerin çalışmasını etkilemeyecektir.

Platform, sınıf yükleyicinin döndürdüğü sınıf tanımlayıcısının beklenen açıklayıcıyla eşleşip eşleşmediğini kontrol eder. Döndürülen açıklayıcı eşleşmezse platform bir NoClassDefFoundError hatası verir ve istisnada tutarsızlığı belirten ayrıntılı bir mesaj depolar.

Platform, istenen sınıfların tanımlayıcılarının geçerli olup olmadığını da kontrol eder. Bu denetim, GetFieldID() gibi sınıfları dolaylı olarak yükleyen JNI çağrılarını yakalayarak söz konusu sınıflara geçersiz tanımlayıcılar aktarır. Örneğin, java/lang/String imzasına sahip bir alan bulunamadığı için bu imzanın Ljava/lang/String; olması gerekir.

Bu, FindClass() için yapılan JNI çağrısından farklıdır. Burada java/lang/String, geçerli bir tam nitelikli addır.

Android 8.0 (API düzeyi 26), birden çok sınıf yükleyicinin aynı DexFile nesnesini kullanarak sınıf tanımlamayı denemesini desteklemez. Bunu yapmaya çalışmak Android çalışma zamanının "Birden çok sınıf yükleyiciyle <filename> dex dosyasını kaydetmeyi dene" mesajıyla InternalError hata yapmasına neden olur.

DexFile API kullanımdan kaldırıldı. Bunun yerine, PathClassLoader veya BaseDexClassLoader dahil olmak üzere platform classloader'larından birini kullanmanız kesinlikle önerilir.

Not: Dosya sistemindeki aynı APK veya JAR dosya kapsayıcısına referans veren birden fazla sınıf yükleyici oluşturabilirsiniz. Normalde bu işlem bellek ek yükünün fazla olmasına yol açmaz: Kapsayıcıdaki DEX dosyaları sıkıştırılmak yerine depolanıyorsa platform, bu dosyaları doğrudan çıkarmak yerine bunlar üzerinde bir mmap işlemi gerçekleştirebilir. Ancak, platformun DEX dosyasını container'dan çıkarması gerekiyorsa DEX dosyasına bu şekilde referans vermek çok fazla bellek tüketebilir.

Android'de tüm sınıf yükleyicilerin paralel özellikli olduğu kabul edilir. Birden çok iş parçacığı aynı sınıfı aynı sınıf yükleyiciyle yüklemek için yarışırsa işlemi tamamlayan ilk iş parçacığı kazanır ve sonuç diğer iş parçacıkları için kullanılır. Bu davranış, sınıf yükleyicinin aynı sınıfı veya farklı bir sınıf döndürüp döndürmediğinden ya da bir istisna oluşturup oluşturmadığından bağımsız olarak gerçekleşir. Platform bu tür istisnaları sessizce dikkate almaz.

Dikkat: Platformun Android 8.0'dan (API seviyesi 26) önceki sürümlerinde bu varsayımların kırılması, aynı sınıfın birden çok kez tanımlanmasına, sınıf karışıklığı nedeniyle yığın bozulmasına ve diğer istenmeyen etkilere yol açabilir.