Android 8.0 Davranış Değişiklikleri

Android 8.0 (API seviyesi 26), yeni özellikler ve özelliklerin 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, hangi Android sürümünü hedeflediklerine bakılmaksızın tüm uygulamaları etkiler. Bununla birlikte, bazı değişiklikler yalnızca Android 8.0'ı hedefleyen uygulamaları etkilemektedir. Anlaşılırlığı en üst düzeye çıkarmak için bu sayfa iki bölüme ayrılmıştır: Tüm uygulamalar için değişiklikler ve Android 8.0'ı hedefleyen uygulamalarla ilgili 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çerli olur. Tüm geliştiriciler bu değişiklikleri incelemeli ve uygulama için uygun olduğu durumlarda uygulamalarını doğru şekilde destekleyecek şekilde düzenlemelidir.

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şenler olmadan önbelleğe alındı durumuna geçtiğinde sistem, uygulamanın tuttuğu tüm 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 artık arka plan hizmetlerine erişim serbestliği konusunda sınırlamalar vardır.
  • Uygulamalar çoğu örtülü yayına (yani, özel olarak uygulamaya hedeflenmeyen yayınlara) kaydolmak için manifestlerini kullanamaz.

Varsayılan olarak, bu kısıtlamalar yalnızca O'yu hedefleyen uygulamalar için geçerlidir. 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 yapılan aşağıdaki değişiklikleri de içerir:

  • 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, arka plandayken bile uygulamaların Context.startForegroundService() yöntemini ç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 daha az konum güncellemesi 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 etkiler:

  • Ç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 son konum API'lerini kullandığınızdan emin olun.
  • Uygulamanızın her kullanım alanı için beklediğiniz davranışı sergileyip sergilemediğini test edin.
  • Kullanıcının mevcut konumuna bağlı olan kullanım alanlarını ele almak için Çok Kaynaklı Konum Sağlayıcı (FLP) veya coğrafi sınır çizmeden yararlanabilirsiniz.

Bu değişiklikler hakkında daha fazla bilgi için Arka Planda Konum Sınırları'na 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 gizli ve dolaylı bir yayın olduğundan com.android.launcher.action.INSTALL_SHORTCUT yayınının uygulamanız üzerinde bir etkisi yok. Bunun yerine, ShortcutManager sınıfından requestPinShortcut() yöntemini kullanarak bir uygulama kısayolu oluşturmalısınız.
  • 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şim kurmayan eski başlatıcı kısayolları da oluşturabilir. Daha önce, bu intent yalnızca eski başlatıcı kısayolları 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ı olur. Bunun sonucunda, uygulamalar artık ShortcutManager içindeki yöntemleri kullanarak bunları 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ı hale getirme

Android 7.0 (API düzeyi 24), varsayılan Kategori Yerel Ayarı belirtebilme kavramını ortaya koydu ancak bazı API'ler, 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 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 sırası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.

    Artık yaygın olarak, 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 kullanıldığında ö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ırken aşağıdaki pencere türlerinden birini kullanarak uyarı pencerelerini diğer uygulamaların ve sistem pencerelerinin üzerinde görüntülemeye çalışırsa:

...daha sonra bu pencereler her zaman TYPE_APPLICATION_OVERLAY pencere türünü kullanan pencerelerin altında görünür. Bir uygulama Android 8.0'ı (API düzeyi 26) hedefliyorsa uyarı pencerelerini görüntülemek için TYPE_APPLICATION_OVERLAY pencere türünü kullanır.

Daha fazla bilgi edinmek istiyorsanız 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 gezinme giriş cihazı olarak kullanma konusunu düzelttik. Böylece ok ve sekme tabanlı gezinme için daha güvenilir, tahmin edilebilir bir model ortaya çıktı.

Ö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 vurgu rengi ayarlar. Odak vurgulaması, etkinliğin temasına dayalı bir dalga çekilebilirliğidir.

    Bir View nesnesinin odak aldığında bu varsayılan vurguyu 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() değerine iletin.

  • Klavye girişinin kullanıcı arayüzü öğesi 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, o anda odaklanılmış öğenin üzerinde "X" simgesi görüntüler.

Ayrıca, Android 8.0'daki tüm araç çubuğu öğeleri otomatik olarak klavye gezinme kümeleridir. Böylece, kullanıcıların araç çubuğuna bir bütün olarak girip çıkması daha kolay olur.

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çevesi, otomatik doldurma işlevi için yerleşik destek sağladığından Android 8.0 (API düzeyi 26) çalıştıran cihazlarda yüklü uygulamalar için WebView nesneleriyle ilgili aşağıdaki yöntemler değişmiştir:

WebSettings
  • getSaveFormData() yöntemi artık false değerini döndürüyor. Daha önce bu yöntem bunun yerine true değerini 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 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 benzer şekilde davranmasını sağlar.

    Uygulamanızın View nesneleri özel dokunma işleme kullanıyorsa TalkBack ile çalışmaya devam ettiklerini 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 nesnelerindeki 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ıkları 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. Bu nedenle, proxy seçimi yalnızca bu değerleri temel alabilir. Özel proxy seçiciye iletilen bir URL; istenen URL'nin yolunu, sorgu parametrelerini veya parçalarını içermiyor.
  • URI'lar boş etiketler içeremez.

    Önceden platform, ana makine adlarında boş etiketlerin kabul edilmesiyle ilgili bir geçici çözümü destekliyordu. Bu, URI'ların yasa dışı bir kullanımıdır. Bu geçici çözüm, eski libcore sürümleriyle uyumluluk için geliyordu. API'yi hatalı bir şekilde kullanan geliştiriciler şu hata mesajını görür: "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’da 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:
    • Sistem, bağlantı üzerinden HTTPS bağlantısını tünellerken, 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 proxy sunucusuna kullanıcı aracısı ve proxy yetkilendirme üst bilgileri göndermez.

      Sistem artık tünel ayarlanırken proxy'ye tünelli Http(s)URLConnection bağlantısında proxy yetkilendirme ü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 bunu proxy'ye gönderir.

      Benzer şekilde, sistem artık tünelli istekten kullanıcı aracısı üst bilgisini tüneli oluşturan proxy isteğine kopyalamaz. Bunun yerine, kitaplık bu istek için bir kullanıcı aracısı 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 döndürür.
    • DatagramSocket.connect(), dahili bir hata varsa bir pendingSocketException ayarlar. Android 8.0'dan önce, bir send() çağrısı başarılı olsa bile sonraki bir 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.
    • Bağlantı noktası 7'yi (TCP Echo) engelleyen google.com gibi bazı ana makineler, 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 gelmeden önce geçen sürenin iki katı olduğu 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, ortaya çıkan 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.

Kolay 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ında yüksek kaliteli kayıtlı bir ağ olduğunda kablosuz bağlantı otomatik olarak etkinleştirilir.

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ış bir şekilde uygulayan bir sunucuyla HTTPS bağlantısı kurulurken, HttpsURLConnection artık önceki TLS protokolü sürümlerine geri dönme ve yeniden deneme geçici çözümünü denememektedir.
  • Android 8.0 (API düzeyi 26), tüm uygulamalara Güvenli Bilişim (SECCOMP) filtresi uygular. İzin verilen syscall'ların listesi, biyonik aracılığıyla açığa çıkanlarla sınırlıdır. Geriye dönük uyumluluk için sunulan başka syscall'lar olsa da bunları kullanmamanızı ö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ı olan uygulamanın sürecinden ayrı ve izole bir süreçte 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 güvenmemelidir.
  • Yerel kitaplıkların kullanımıyla ilgili güvenlik geliştirmeleri hakkında bilgi edinmek için Yerel Kitaplıklar bölümünü inceleyin.

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

Bilinmeyen uygulamaları yüklemeyle ilgili daha fazla bilgi 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 konusuna bakı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şliyor.
    • OTA sürümünden önce Android 8.0 (API düzeyi 26) (API düzeyi 26) sürümüne yüklenen uygulamalarda 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 gerçekleşen kaldırma işlemlerinin değerlerini korumak için Anahtar/Değer Yedekleme'yi 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 uygulama imzalama anahtarı ve kullanıcı başına kapsama dahil edilir. Her bir uygulama imzalama anahtarı, kullanıcı ve cihaz kombinasyonu için ANDROID_ID değeri benzersizdir. Sonuç olarak, aynı cihazda çalışan farklı imzalama anahtarları bulunan 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şlemlerinde 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 ve kullanıcı tarafından sıfırlanabilen benzersiz bir kimliktir. Google Play Hizmetleri tarafından sağlanır.

      Diğer cihaz üreticileri ANDROID_ID sağlayıcısını sağlamaya devam etmelidir.

  • net.hostname sistem özelliğini sorgulamak boş bir sonuç üretir.

Yakalanmayan istisnaların günlüğe kaydedilmesi

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

Özel Thread.UncaughtExceptionHandler uygulamalarının her zaman varsayılan işleyiciye yönlendirme yapması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çları doğuracak:

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

Kişi sağlayıcı kullanım istatistikleri değişikliği

Android'in önceki sürümlerinde, Kişi Sağlayıcı bileşeni, geliştiricilerin her bir kişinin kullanım verilerini almasına olanak tanır. Bu kullanım verileri, bir kişiyle ilişkilendirilmiş her bir e-posta adresi ve telefon numarasına ilişkin bilgileri (kişiyle kaç kez iletişim kurulduğu 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ğerler 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:

Koleksiyon işleme

AbstractCollection.removeAll() ve AbstractCollection.retainAll() artık her zaman bir NullPointerException gönderiyordu; önceden, koleksiyon boşken NullPointerException atılmıyordu. Bu değişiklik, davranışı dokümanlarla tutarlı hale getirir.

Android Enterprise

Android 8.0 (API düzeyi 26), cihaz politikası denetleyicileri (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'i 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 öğesini 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 üzerinde 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ünü 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 gösterimini 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ü kullanılarak 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ın ContentResolver.notifyChange() ve registerContentObserver(Uri, boolean, ContentObserver) çalışma biçimini 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 yapılan 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 olmasını ancak odaklanılabilir olmamasını istiyorsanız View 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:

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 amacıyla Opera tarayıcısı için 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ğini desteklemeyi 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ın yerine Bilinmeyen uygulamaları yükleme izni, bilinmeyen kaynaklardan 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 konusuna bakın.

Hesaba erişim ve bulunabilirlik

Android 8.0'da (API düzeyi 26) uygulamalar, kimlik doğrulayıcının sahibi olmadığı veya kullanıcı erişim izni vermediği sürece kullanıcı hesaplarına artık erişemez. GET_ACCOUNTS izni artık yeterli değildir. Uygulamaların bir hesaba erişim izni almak için AccountManager.newChooseAccountIntent() veya kimlik doğrulayıcıya özel bir yöntem kullanması gerekir. Hesaplara erişim izni aldıktan sonra, uygulama AccountManager.getAccounts() numaralı telefonu arayarak bu hesaplara erişebilir.

Android 8.0 için destek sonlandırılıyor LOGIN_ACCOUNTS_CHANGED_ACTION. Uygulamalar, çalışma zamanında hesaplarla ilgili güncellemeleri 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 artıran 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ğ bilgilerini elde etmek için NetworkRequest veya NetworkCallback nesnesini 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 vermez. Bir kullanıcı 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 olur.

İzinler

Android 8.0'dan (API düzeyi 26) önce, bir uygulama çalışma zamanında izin istediyse ve izin verildiyse sistem, uygulamaya aynı izin grubuna ait olan ve manifest'te kayıtlı diğer izinleri de yanlışlıkla 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 izin verdiğinde bu izin grubundaki sonraki tüm izin istekleri otomatik olarak onaylanır.

Ö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ı bu isteği kabul ediyor. Uygulama, API düzeyi 25 veya altını hedefliyorsa sistem, aynı STORAGE izin grubuna ait olması ve aynı zamanda manifest'te kayıtlı olması nedeniyle 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 sesi kısma işlemi gerçekleştirebilir. Bu durumda, AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ile odaklanmayı sağlayan başka bir uygulama, ses düzeyini düşürür ancak genellikle onAudioFocusChange() geri çağırmasını 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ılabilir.
  • Kullanıcı telefon görüşmesi yaptığında etkin medya akışlarının sesi arama süresince kapatılı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 istiyorsa çerçeve, mümkünse 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. Medya düğmesi etkinliklerini alacak uygulama belirlenirken medya oturumunun etkin durumu, işaretleri ve oynatma durumu 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. Diğer her durumda sistem, 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 bir 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, uygulamanın hedeflediği API düzeyine bağlıdır. Hedeflenen API düzeyinde bir bağlayıcı değişikliği olursa 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.

Koleksiyon işleme

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

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

  • List.sort() uygulamaları, Collections.sort() yöntemini çağırmamalıdır. Çünkü bu işlem, sonsuz tekrarlama nedeniyle yığın taşmasına neden olur. Bunun yerine, List uygulamanızda varsayılan davranışı istiyorsanız sort() değerini geçersiz kılmaktan kaçınmalısınız.

    Bir üst sınıf sort() öğesini uygunsuz bir şekilde uygularsa List.sort(), List.toArray(), Arrays.sort() ve ListIterator.set() üzerine oluşturulmuş bir uygulamayla geçersiz kılınabilir. Örneğin:

    @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. Örneğin:

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

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

  • Collections.sort() artık sort() yöntemini çağıran Liste uygulamalarında yapısal değişiklik olarak sayılır. Örneğin, platformun Android 8.0'dan (API düzeyi 26) önceki sürümlerinde bir ArrayList yinelemesi ve yinelemenin yarısında sort() çağrısı yapılması, sıralama List.sort() çağrısıyla yapıldıysa ConcurrentModificationException sonucunu döndürür. Collections.sort() istisna oluşturmadı.

    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ığını kontrol eder. Bu kontroller, sınıfın Java (forName() kaynaklı), Dalvik bayt kodu veya JNI üzerinden referans alınıp alınmadığı gerçekleştirilir. Platform, Java'dan loadClass() yöntemine yapılan doğrudan çağrılara müdahale etmez 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 tanımlayı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 bu sınıflara geçersiz tanımlayıcılar iletir. Örneğin, java/lang/String imzasına sahip bir alan, geçersiz olduğundan bulunamadı. İmza Ljava/lang/String; olmalıdır.

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ıfları tanımlamayı denemesini desteklemez. Bunu yapma girişimi, Android çalışma zamanının "Birden çok sınıf yükleyiciyle <filename> dex dosyasını kaydetmeyi deneme" mesajıyla InternalError bir hata vermesine neden olur.

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

Not: Dosya sistemindeki aynı APK veya JAR dosya kapsayıcısına referans veren birden fazla sınıf yükleyici oluşturabilirsiniz. Bu işlem normalde fazla bellek ek yüküne neden olmaz: Kapsayıcıdaki DEX dosyaları sıkıştırılmak yerine depolanıyorsa platform, dosyaları doğrudan ayıklamak yerine bunlar üzerinde bir mmap işlemi gerçekleştirebilir. Ancak platformun DEX dosyasını kapsayıcıdan çıkarması gerekiyorsa DEX dosyasına bu şekilde referans vermek çok fazla bellek kullanabilir.

Android'de, tüm sınıf yükleyicilerin paralel özellikli olduğu kabul edilir. Birden fazla 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ükleyicisinin aynı sınıfı veya farklı bir sınıf döndürüp döndürmediğinden ya da 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 düzeyi 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.