Android 8.0 Davranış Değişiklikleri

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

Bu değişikliklerin çoğu, hedefledikleri Android sürümünden bağımsız olarak tüm uygulamaları etkiler. Bununla birlikte, bazı değişiklikler yalnızca Android 8.0'ı hedefleyen uygulamaları etkiler. Anlaşılırlığı en üst düzeye çıkarmak için bu sayfa Tüm uygulamalar için değişiklikler ve Android 8.0'ı hedefleyen uygulamalar için değişiklikler olmak üzere iki bölüme ayrılmıştır.

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

Bu davranış değişiklikleri, hedefledikleri API düzeyinden bağımsız olarak 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 uygulamalarında bu değişiklikleri gerektiği şekilde destekleyecek şekilde değişiklik yapmalıdır.

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

Android 8.0 (API düzeyi 26), pil ömrünü iyileştirmek için uygulamanızın etkin bileşenleri olmadan önbelleğe alınmış duruma girmesiyle ilgili bir değişiklik yaptı. Bu durumda sistem, uygulamanın tuttuğu tüm uyanma kilitlerini serbest bırakır.

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

  • Arka planda çalışan uygulamalar artık arka plan hizmetlerine ne kadar özgürce erişebilecekleri konusunda sınırlamalara tabidir.
  • Uygulamalar, çoğu dolaylı yayına (yani, özellikle uygulamayı hedeflemeyen yayınlara) kaydolmak için manifest dosyalarını 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 bu kısıtlamaları Ayarlar ekranından herhangi bir uygulama için etkinleştirebilir.

Android 8.0 (API seviyesi 26), belirli yöntemlerde aşağıdaki değişiklikleri de içerir:

  • Android 8.0'ı hedefleyen bir uygulama, arka plan hizmeti oluşturmaya izin verilmeyen bir durumda bu yöntemi kullanmaya çalışırsa startService() yöntemi artık bir IllegalStateException hatası atıyor.
  • Yeni Context.startForegroundService() yöntemi, bir ön plan hizmetini başlatır. Sistem, uygulamaların arka plandayken bile Context.startForegroundService() çağrısı yapması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 Planda Çalıştırma Sınırları başlıklı makaleyi inceleyin.

Android arka planda konum sınırlamaları

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

Bu değişiklikler aşağıdaki API'leri etkiler:

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

Uygulamanızın beklendiği gibi çalışmasını sağlamak 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ında beklediğiniz davranışı sergileyip sergilemediğini test edin.
  • Kullanıcının mevcut konumuna bağlı kullanım alanlarını yönetmek için Fused Location Provider (FLP)'ı veya coğrafi sınırlamayı kullanabilirsiniz.

Bu değişiklikler hakkında daha fazla bilgi için Arka Planda Konum Sınırlamaları başlıklı makaleyi inceleyin.

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ğu için com.android.launcher.action.INSTALL_SHORTCUT yayını uygulamanızı etkilemez. Bunun yerine, ShortcutManager sınıfındaki requestPinShortcut() yöntemini kullanarak bir uygulama kısayolu oluşturmalısınız.
  • ACTION_CREATE_SHORTCUT intent artık ShortcutManager sınıfını kullanarak yönettiğiniz uygulama kısayolları oluşturabilir. Bu intent, ShortcutManager ile etkileşime girmeyen 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 intent'ini işleyen bir etkinlikte oluşturulan kısayollar artık tam teşekküllü uygulama kısayollarıdır. Sonuç olarak, uygulamalar artık ShortcutManager'teki 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 özellik kılavuzuna bakın.

Yerel ayarlar ve uluslararasılaştırma

Android 7.0 (API düzeyi 24), varsayılan bir kategori yerel dili belirtme konseptini kullanıma sundu ancak bazı API'ler, varsayılan DISPLAY kategori yerel dilini kullanmaları gerekirken genel Locale.getDefault() yöntemini bağımsız değişken olmadan kullanmaya devam etti. Android 8.0 (API düzeyi 26) sürümünde, aşağıdaki yöntemlerde artık Locale.getDefault() yerine Locale.getDefault(Category.DISPLAY) kullanılmaktadır:

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

Yerel ayar ve uluslararasılaştırmayla ilgili diğer değişiklikler şunlardır:

  • Currency.getDisplayName(null) çağrısı, belgelenen davranışla eşleşen bir NullPointerException oluşturur.
  • Saat dilimi adı ayrıştırması değişti. Daha önce Android cihazlar, tarih saatlerini ayrıştırmada kullanılan saat dilimi adlarını önbelleğe almak için başlatma anında örneklenen sistem saat değerini kullanıyordu. Sonuç olarak, sistem saati önyükleme sırasında yanlışsa veya daha nadir görülen diğer durumlarda ayrıştırma olumsuz yönde etkilenebilir.

    Artık, zaman dilimi adlarını ayrıştırırken ayrıştırma mantığı genellikle ICU'yu ve geçerli sistem saati değerini kullanıyor. Bu değişiklik daha doğru sonuçlar sağlar. Uygulamanız SimpleDateFormat gibi sınıfları kullandığında bu sayı, önceki Android sürümlerinden farklı olabilir.

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

Uyarı pencereleri

Bir uygulama, SYSTEM_ALERT_WINDOW iznini kullanıyorsa ve diğer uygulamaların ve sistem pencerelerinin üzerinde uyarı pencereleri göstermeye ç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) hedefleyen uygulamalar, uyarı pencerelerini 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 ile ilgili davranış değişikliklerindeki Uyarı pencereleri için yaygın pencere türleri bölümünü inceleyin.

Giriş ve gezinme

ChromeOS'te Android uygulamalarının ve tabletler gibi diğer geniş form faktörlerinin ortaya çıkmasıyla birlikte, Android uygulamalarında klavyeyle gezinmenin yeniden yükseldiğini görüyoruz. Android 8.0'da (API seviyesi 26) klavyeyi gezinme giriş cihazı olarak kullanmayı yeniden ele aldık. Bu sayede, ok ve sekme tabanlı gezinme için daha güvenilir ve tahmin edilebilir bir model elde ettik.

Özellikle, öğe odaklanma 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 noktası rengi ayarlar. Bu odaklanma vurgusu, etkinliğin temasına dayalı bir dalga çizilebilir öğedir.

    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ıkındaki setDefaultFocusHighlightEnabled() öğesine false değerini 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, şu anda odaklandırılmış öğenin üzerinde bir "X" simgesi gösterir.

Ayrıca Android 8.0'daki tüm araç çubuğu öğeleri otomatik olarak klavye gezinme kümeleri haline getirilir. Bu sayede kullanıcılar her bir araç çubuğuna tek bir birim olarak girip çıkabilir.

Uygulamanızda klavyeyle gezinme desteğini nasıl iyileştireceğiniz hakkında daha fazla bilgi edinmek için Klavyeyle gezinmeyi destekleme kılavuzunu okuyun.

Web formu otomatik doldurma

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 cihazlara yüklenen uygulamalarda WebView nesneleriyle ilgili aşağıdaki yöntemler değişti:

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() çağrısı artık herhangi bir etkisi yoktur.
WebViewDatabase
  • clearFormData() çağrısı artık herhangi bir etkisi yoktur.
  • 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 çift dokunma hareketlerini ACTION_CLICK işlemlerine dönüştürüyor. Bu değişiklik, TalkBack'in diğer erişilebilirlik hizmetlerine daha çok benzer davranışlarda bulunmasını sağlar.

    Uygulamanızın View nesneleri özel dokunma işlemeyi kullanıyorsa bunların TalkBack ile çalışmaya devam ettiğini doğrulamanız gerekir. ViewÖğelerinizin kullandığı tıklama işleyiciyi kaydettirmeniz yeterli olabilir. TalkBack bu nesnelerde yapılan hareketleri hâlâ tanımıyorsa View öğesini geçersiz kılın.performAccessibilityAction()

  • Erişilebilirlik hizmetleri artık uygulamanızın TextView nesnelerindeki tüm ClickableSpan örneklerini biliyor.

Uygulamanızı daha erişilebilir hale getirme hakkında daha fazla bilgi edinmek için Erişilebilirlik konusuna bakın.

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

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

  • Gövde içermeyen OPTIONS isteklerinde Content-Length: 0 başlığı bulunur. Daha önce Content-Length üstbilgisi yoktu.
  • HttpURLConnection, ana makine veya yetkili adından sonra eğik çizgi ekleyerek boş yollar içeren URL'leri normalize eder. Örneğin, http://example.com değerini http://example.com/ değerine 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 dayalı olabilir. Özel bir proxy seçiciye iletilen URL, istenen URL'nin yolunu, sorgu parametrelerini veya parçalarını içermez.
  • URI'ler boş etiket içeremez.

    Daha önce platform, ana makine adlarında boş etiketleri kabul etmek için bir geçici çözümü destekliyordu. Bu, URI'lerin yasa dışı bir şekilde kullanılmasıdır. Bu geçici çözüm, eski libcore sürümleriyle uyumluluk içindi. API'yi yanlış kullanan geliştiriciler şu ADB mesajını görür: "URI example..com, ana makine adında boş etiketlere sahip. Bu, hatalı biçimlendirilmiş ve gelecekteki Android sürümlerinde kabul edilmeyecektir." Android 8.0 bu geçici çözümü kaldırır. Sistem, hatalı biçimlendirilmiş URI'ler için null döndürür.

  • Android 8.0'da HttpsURLConnection uygulaması, güvenli olmayan TLS/SSL protokolü sürümü yedeği gerçekleştirmez.
  • HTTP(S) tünel bağlantılarının işlenmesi aşağıdaki şekilde değiştirilmiştir:
    • Sistem, HTTPS bağlantısını bağlantı üzerinden tünel yaparken bu bilgileri bir ara sunucuya gönderirken bağlantı noktası numarasını (:443) Ana Makine satırına doğru şekilde yerleştirir. Daha önce bağlantı numarası yalnızca CONNECT satırında yer alıyordu.
    • Sistem artık tünellenmiş bir istekteki user-agent ve proxy-authorization başlıklarını proxy sunucusuna göndermiyor.

      Sistem artık tüneli kurarken proxy'ye tünele alınmış bir Http(s)URLConnection üzerinde proxy yetkilendirme başlığı göndermiyor. Bunun yerine sistem, bir proxy yetkilendirme başlığı oluşturur ve bu proxy ilk isteğe yanıt olarak HTTP 407 gönderdiğinde başlığı proxy'ye gönderir.

      Benzer şekilde sistem artık kullanıcı aracısı başlığını, tünellenmiş istek Bunun yerine kitaplık, söz konusu istek için bir kullanıcı aracısı başlığı oluşturur.

  • Daha önce çalıştırılan connect() yöntemi başarısız olursa send(java.net.DatagramPacket) yöntemi bir SocketException oluşturur.
    • Dahili bir hata varsa DatagramSocket.connect(), pendingSocketException değerini ayarlar. Android 8.0'dan önce, send() çağrısı başarılı olsa bile sonraki recv() çağrısı bir SocketException hatası fırlatıyordu. Tutarlılık için her iki çağrı da artık SocketException hatası veriyor.
  • InetAddress.isReachable(), TCP Echo protokolüne geçmeden önce ICMP'yi dener.
    • 7 numaralı bağlantı noktasını (TCP Echo) engelleyen bazı barındırıcılar (ör. google.com), ICMP Echo protokolünü kabul ederse artık erişilebilir hale gelebilir.
    • Gerçekten erişilemeyen ana makineler için bu değişiklik, aramanın döndürülmesinden önce iki kat daha fazla süre harcanacağı 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 hiçbir varsayım yapmaz. Bu nedenle, uygulamalar döndürülen minimum veya maksimum bayt sayısına güvenmemelidir. Bunun yerine, elde edilen dizinin uzunluğunu değerlendirmelidir.
  • Bluetooth 5 uyumlu cihazlar, bir önceki maksimum değer olan ~60 baytı aşan veri uzunluğu döndürebilir.
  • Uzak cihaz tarama yanıtı sağlamazsa 60 bayttan az veri de 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 yapılmaktadır. Belirli değişikliklerden bazıları şunlardır:

  • Kararlılık ve güvenilirlikle ilgili iyileştirmeler.
  • Sezgisel olarak daha okunabilir bir kullanıcı arayüzü.
  • Tek bir birleşik kablosuz tercihleri menüsü.
  • Uyumlu cihazlarda, yüksek kaliteli kayıtlı bir ağ yakındayken kablosuz özelliğinin otomatik olarak etkinleştirilmesi.

Güvenlik

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

  • Platform artık SSLv3'ü desteklemiyor.
  • TLS protokolü sürümünü yanlış uygulayan bir sunucuya HTTPS bağlantısı kurarken HttpsURLConnection artık önceki TLS protokolü sürümlerine geri dönüp yeniden deneme çözümünü denemeyecek.
  • Android 8.0 (API düzeyi 26), tüm uygulamalara Güvenli Bilgisayar İşleme (SECCOMP) filtresi uygular. İzin verilen syscall'lar listesi, biyonik ile maruz kalan syscall'larla sınırlıdır. Geriye dönük uyumluluk için sağlanan başka sistem çağrıları olsa da bunların kullanılmamasını öneririz.
  • Uygulamanızın WebView nesneleri artık çok işlemli modda çalışıyor. Web içeriği, daha fazla güvenlik için içeren uygulamanın işleminden ayrı, izole bir işlemde işlenir.
  • Artık APK'ların adları -1 veya -2 ile biten dizinlerde bulunduğunu varsayamazsınız. Uygulamalar, doğrudan dizin biçimine bağlı kalmamalı, dizini almak için sourceDir kullanmalıdır.
  • Yerel kitaplıkların kullanımıyla ilgili güvenlik geliştirmeleri hakkında bilgi edinmek için Yerel Kitaplıklar başlıklı makaleyi inceleyin.

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

Bilinmeyen uygulamaları yükleme hakkında 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 sayfasını inceleyin.

Gizlilik

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

  • Platform artık tanımlayıcıları farklı şekilde ele alıyor.
    • OTA'dan önce Android 8.0 (API düzeyi 26) sürümüne (API düzeyi 26) yüklenen uygulamalarda, OTA'dan sonra kaldırılıp yeniden yüklenmediği sürece ANDROID_ID değerinin değeri aynı kalır. OTA'dan sonra kaldırma işlemlerinde değerleri korumak için geliştiriciler anahtar/değer yedekleme özelliğini kullanarak eski ve yeni değerleri ilişkilendirebilir.
    • Android 8.0 çalıştıran bir cihaza yüklenen uygulamalar için ANDROID_ID değeri artık kullanıcı ve uygulama imzalama anahtarı için kapsama alınır. ANDROID_ID değerinin değeri, her uygulama imzalama anahtarı, kullanıcı ve cihaz kombinasyonu için benzersizdir. Sonuç olarak, aynı cihazda çalışan farklı imzalama anahtarlarına sahip uygulamalar artık aynı Android kimliğini görmez (aynı kullanıcı için bile).
    • İmzalama anahtarı aynı olduğu sürece (ve uygulama, Android 8.0'a OTA güncellemesinden önce yüklenmemişse) ANDROID_ID değerinin paketin kaldırılması veya yeniden yüklenmesi durumunda değişmemesi
    • Bir 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 birlikte gönderilen cihazlarda reklam kimliğini kullanmanız gerekir. Uygulamalardan para kazanmak için kullanılan basit, standart bir sistem olan reklam kimliği, reklamcılık için 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ğlamaya devam etmelidir.

  • net.hostname sistem mülküne sorgu gönderdiğinizde null sonuç döndürülür.

Yakalanmayan istisnaları günlüğe kaydetme

Bir uygulama, varsayılan Thread.UncaughtExceptionHandler'a çağrı yapmayan bir Thread.UncaughtExceptionHandler yüklerse yakalanmayan bir istisna oluştuğunda sistem uygulamayı kapatmaz. Android 8.0 (API düzeyi 26) sürümünden itibaren sistem, bu durumda istisna yığın izlemesini günlüğe kaydeder. Platformun önceki sürümlerinde sistem, istisna yığın izlemesini günlüğe kaydetmez.

Özel Thread.UncaughtExceptionHandleruygulamaların her zaman varsayılan işleyiciyi çağırmasını öneririz. Bu öneriye uyan 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şiklikle birlikte aşağıdakiler de geçerli olacaktır:

  • Bu durum, mevcut kodun artık belirsiz bir dönüş türüne sahip olmasına neden olabilir. Örneğin, findViewById() çağrısının sonucunu alan hem someMethod(View) hem de someMethod(TextView) varsa.
  • Java 8 kaynak dili kullanıldığında, döndürülen tür sınırsız olduğunda (örneğin, assertNotNull(findViewById(...)).someViewMethod())) View değerine açıkça bir dönüştürme işlemi gerekir.
  • Nihai olmayan findViewById() yöntemlerinin (ör. Activity.findViewById()) geçersiz kılma işlemlerinin döndürülen türünün güncellenmesi gerekir.

Kişi sağlayıcısı 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şi için kullanım verilerini almasına olanak tanır. Bu kullanım verileri, bir kişiyle ilişkili her e-posta adresi ve her telefon numarasına ait bilgileri açığa çıkarır. Bu bilgiler, söz konusu kişiyle kaç kez iletişime geçildiği ve kişiyle en son ne zaman iletişime geçildiği de dahildir. READ_CONTACTS izinini isteyen uygulamalar bu verileri okuyabilir.

Uygulamalar, READ_CONTACTS iznine sahipse bu verileri okumaya devam edebilir. Android 8.0 (API düzeyi 26) ve sonraki sürümlerde, kullanım verileri 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:

Toplama işlemleri

AbstractCollection.removeAll() ve AbstractCollection.retainAll() artık her zaman bir NullPointerException oluşturur; daha önce, koleksiyon boşken NullPointerException oluşturulmazdı. Bu değişiklik, davranışın belgelerle tutarlı olmasını sağlar.

Android Enterprise

Android 8.0 (API düzeyi 26), cihaz politikası denetleyiciler (DPC'ler) dahil olmak üzere kurumsal uygulamalara yönelik bazı API'lerin ve özelliklerin davranışını değiştirir. Yapılan değişikliklerden bazıları ş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ğrulama işlemlerinde yapılan değişiklikler.
  • Hazırlama, bildirimler, Son Aramalar ekranı ve her zaman açık VPN ile ilgili kullanıcı deneyiminde iyileştirmeler.

Android 8.0 (API seviyesi 26)'daki tüm kurumsal değişiklikleri görmek ve bunların uygulamanızı nasıl etkileyebileceğini öğrenmek için Kurumsal Ortamda Android başlıklı makaleyi okuyun.

Android 8.0'ı hedefleyen uygulamalar

Bu davranış değişiklikleri yalnızca Android 8.0 (API seviyesi 26) veya sonraki sürümleri hedefleyen uygulamalar için geçerlidir. Android 8.0'da derleme yapan veya targetSdkVersion değerini Android 8.0 ya da sonraki bir sürüme ayarlayan uygulamalar, geçerli olduğu durumlarda uygulamalarını bu davranışları doğru şekilde destekleyecek şekilde 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ın TYPE_APPLICATION_OVERLAY adlı yeni bir pencere türü kullanması gerekir.

Uygulamanızda 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:

  • Uygulamaların uyarı pencereleri her zaman durum çubuğu ve IME'ler gibi kritik sistem pencerelerinin altında görünür.
  • Sistem, ekran görüntüsünü 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 engelleme ayarlarına erişebilir.

İçerik değişikliği bildirimleri

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

Bu API'ler artık tüm Uri'lerde otorite için geçerli bir ContentProvider tanımlanmasını zorunlu kılıyor. İlgili izinlere sahip geçerli bir ContentProvider tanımlamak, uygulamanızın kötü amaçlı uygulamalardan gelen içerik değişikliklerine karşı korunmasına yardımcı olur ve gizli olabilecek verileri kötü amaçlı uygulamalara sızdırmanızı önler.

Odağı göster

Tıklanabilir View nesnelerine artık varsayılan olarak 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ıkındaki setFocusable() öğesine false değerini iletin.

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

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 dışındaki bir tarayıcıyı Opera olarak yanlış tanımlamasına neden olabilir. Bu tür bir kalıp eşleşmesine örnek olarak aşağıdakiler verilebilir:

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

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

Güvenlik

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

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

Uygulamanızı daha güvenli hale getirme konusunda ek yönergeler için Android Geliştiricileri için Güvenlik sayfasını inceleyin.

Hesaba erişim ve bulunabilirlik

Android 8.0 (API düzeyi 26) sürümünden itibaren, kimlik doğrulayıcı hesapların sahibi olmadığı veya kullanıcının erişim izni vermediği sürece uygulamalar kullanıcı hesaplarına erişemez. GET_ACCOUNTS izni artık yeterli değil. Uygulamaların hesaba erişebilmesi için AccountManager.newChooseAccountIntent() veya kimlik doğrulayıcıya özgü bir yöntem kullanması gerekir. Hesaplara erişen uygulamalar, bu hesaplara erişmek için AccountManager.getAccounts() işlevini çağırabilir.

Android 8.0'da LOGIN_ACCOUNTS_CHANGED_ACTION desteği sonlandırıldı. Uygulamalar, çalışma zamanında hesaplar hakkında güncelleme almak için addOnAccountsUpdatedListener() yerine kullanmalıdır.

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

Gizlilik

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

  • net.dns1, net.dns2, net.dns3 ve net.dns4 sistem özellikleri artık kullanılamıyor. Bu değişiklik, platformda gizliliği iyileştiren bir değişikliktir.
  • ACCESS_NETWORK_STATE iznine sahip uygulamalar, DNS sunucuları gibi ağ 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 kullanılabilir.
  • 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 vermiyor. Kullanıcı bir iş profilindeyken LauncherApps API, aynı profil grubundaki diğer profillere hiçbir uygulama yüklenmemiş gibi davranır. Daha önce olduğu gibi, alakasız profillere erişim girişimleri SecurityExceptions'e neden olur.

İzinler

Android 8.0 (API düzeyi 26) öncesinde, bir uygulama çalışma zamanında izin istediyse ve izin verildiyse sistem, uygulamaya aynı izin grubuna ait olan ve manifest dosyasına kaydedilen diğer izinleri de yanlışlıkla veriyordu.

Android 8.0'i hedefleyen uygulamalarda bu davranış düzeltildi. Uygulamaya yalnızca açıkça istediği izinler verilir. Ancak kullanıcı uygulamaya bir izin verdikten sonra, söz konusu izin grubundaki sonraki tüm izin istekleri otomatik olarak verilir.

Örneğin, bir uygulamanın manifest dosyasında hem READ_EXTERNAL_STORAGE hem de WRITE_EXTERNAL_STORAGE listelendiğini varsayalım. Uygulama READ_EXTERNAL_STORAGE isteği gönderir ve kullanıcı izin verir. Uygulama API düzeyi 25 veya daha düşük bir sürümü hedefliyorsa sistem, aynı STORAGE izin grubuna ait olduğu ve manifest dosyasına da kaydedilmiş olduğu için aynı anda WRITE_EXTERNAL_STORAGE iznini de verir. Uygulama Android 8.0'ı (API düzeyi 26) hedefliyorsa sistem o anda yalnızca READ_EXTERNAL_STORAGE hizmetini verir. Ancak, uygulama daha sonra WRITE_EXTERNAL_STORAGE isteğinde bulunursa sistem, kullanıcıya sormadan bu ayrıcalığı hemen verir.

Medya

  • Çerçeve, otomatik ses azaltma işlemini kendi başına gerçekleştirebilir. Bu durumda, başka bir uygulama AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ile odaklanmayı istediğinde, odaklanmaya sahip uygulama ses seviyesini düşürür ancak genellikle onAudioFocusChange() geri çağırma işlevi almaz ve ses odağını kaybetmez. Ekran karartmak yerine duraklatılması gereken uygulamalar için bu davranışı geçersiz kılmak üzere yeni API'ler kullanılabilir.
  • Kullanıcı telefon araması aldığında etkin medya akışları arama süresi boyunca sessize alınır.
  • Sesle ilgili tüm API'lerde, ses oynatma kullanım alanını açıklamak için ses yayını türleri yerine AudioAttributes kullanılmalıdır. Ses yayını türlerini yalnızca ses seviyesi kontrolleri için kullanmaya devam edin. Akış türlerinin diğer kullanımları (örneğin, desteği sonlandırılmış AudioTrack oluşturucusu için streamType bağımsız değişkeni) çalışmaya devam eder ancak sistem bunu hata olarak günlüğe kaydeder.
  • AudioTrack kullanılırken uygulama yeterince büyük bir ses arabelleği talep ederse çerçeve, varsa derin arabellek çıkışını kullanmaya çalışır.
  • Android 8.0 (API düzeyi 26) sürümünde medya düğmesi etkinliklerinin işlenmesi farklıdır:
    1. Kullanıcı arayüzü etkinliğinde medya düğmelerinin işlenmesi değişmedi: Medya düğmesi etkinliklerinin işlenmesi konusunda ön plan etkinlikleri öncelikli olmaya devam ediyor.
    2. Ön plan etkinliği medya düğmesi etkinliğini işlemezse sistem, etkinliği yerel olarak ses çalan en son uygulamaya yönlendirir. Hangi uygulamanın medya düğmesi etkinliklerini alacağı belirlenirken medya oturumunun etkin durumu, işaretleri ve oynatma durumu dikkate alınmaz.
    3. Uygulamanın medya oturumu sonlandırıldıysa sistem, medya düğmesi etkinliğini uygulamanın MediaButtonReceiver'ine (varsa) gönderir.
    4. Diğer tüm durumlarda sistem, medya düğmesi etkinliğini atar.

Yerel kitaplık

Android 8.0'ı (API düzeyi 26) hedefleyen uygulamalarda, hem yazılabilir hem de yürütülebilir herhangi bir yük segmenti içeren yerel kitaplıklar artık yüklenmez. Yanlış yükleme segmentleri içeren yerel kitaplıkları olan bazı uygulamalar bu değişiklik nedeniyle çalışmayı durdurabilir. Bu, güvenlik artırıcı bir önlemdir.

Daha fazla bilgi için Yazılabilir ve Çalıştırılabilir Segmentler başlıklı makaleyi inceleyin.

Bağlantı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ğlantı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.

Koleksiyonları yönetme

Android 8.0'da (API düzeyi 26) Collections.sort(), List.sort() öğesinin üzerine uygulanır. Android 7.x (API düzeyleri 24 ve 25) sürümlerinde bunun tam tersi geçerliydi: List.sort() için varsayılan uygulama Collections.sort() olarak adlandırılıyordu.

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

  • List.sort() uygulamalarının Collections.sort()'u çağırmaması gerekir. Aksi takdirde, sonsuz yineleme nedeniyle yığın taşması meydana gelir. Bunun yerine, List uygulamanızda varsayılan davranışı kullanmak istiyorsanız sort() değerini geçersiz kılmaktan kaçınmalısınız.

    Bir üst sınıf sort()'ü uygunsuz bir şekilde uygularsa List.sort()List.toArray(), Arrays.sort() ve ListIterator.set()'in üzerine inşa edilmiş bir uygulamayla geçersiz kılmak genellikle sorun teşkil etmez. Ö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 de 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);
      }
    }

    İkinci seçeneği, tüm API düzeylerinde kullanılabilir bir sort() yöntemi olmasını istediğiniz için yapıyorsanız sort() yöntemini geçersiz kılmak yerine bu yönteme sortCompat() gibi benzersiz bir ad verin.

  • Collections.sort() artık sort() çağıran liste uygulamalarında yapısal bir değişiklik olarak kabul edilir. Örneğin, platformun Android 8.0 (API düzeyi 26) öncesindeki sürümlerinde, bir ArrayList üzerinde iterasyon gerçekleştirip iterasyonun ortasında sort() çağrılırsa sıralama List.sort() çağrılarak yapılmışsa bir ConcurrentModificationException hatası oluşurdu. Collections.sort() istisna hatası vermedi.

    Bu değişiklik, platform davranışını daha tutarlı hale getiriyor: Her iki yaklaşım da artık 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ı ihlal etmediğinden emin olmayı kontrol eder. Bu kontroller, sınıfa Java'dan (forName()'ten), Dalvik bayt kodundan veya JNI'den referans verilip verilmediğine bakılmaksızın 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ış, iyi davranan sınıf yükleyicilerin işleyişini etkilemez.

Platform, sınıf yükleyicinin döndürdüğü sınıfın tanımlayıcısının beklenen tanımlayıcıyla eşleşip eşleşmediğini kontrol eder. Döndürülen tanımlayıcı eşleşmezse platform bir NoClassDefFoundError hatası gönderir 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 kontrol, GetFieldID() gibi sınıfları dolaylı olarak yükleyen ve bu sınıflara geçersiz tanımlayıcı gönderen JNI çağrılarını yakalar. Örneğin, java/lang/String imzası geçersiz olduğu için alan bulunamadı. Bu alan Ljava/lang/String; olmalıdır.

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

Android 8.0 (API seviyesi 26), birden fazla sınıf yükleyicinin aynı DexFile nesnesini kullanarak sınıfları tanımlamaya çalışmasını desteklemez. Bunu yapmaya çalıştığınızda Android çalışma zamanında "<filename> adlı dex dosyasını birden fazla sınıf yükleyiciye kaydetme girişimi" mesajıyla birlikte bir hata meydana gelir.InternalError

DexFile API'nin desteği sonlandırılmıştır. Bunun yerine PathClassLoader veya BaseDexClassLoader dahil olmak üzere platform sınıf yükleyicilerinden birini kullanmanız önemle tavsiye edilir.

Not: Dosya sisteminden aynı APK veya JAR dosya kapsayıcısına başvuran birden fazla sınıf yükleyici oluşturabilirsiniz. Normalde bu işlem çok fazla bellek ek yüküne neden olmaz: Container'daki DEX dosyaları sıkıştırılmak yerine depolanırsa platform, dosyaları doğrudan çıkarmak yerine bu dosyalar üzerinde 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 tüketebilir.

Android'de tüm sınıf yükleyiciler paralel işleme uygun kabul edilir. Birden fazla iş parçacığı aynı sınıf yükleyiciyle aynı sınıfı yüklemek için yarıştığında, 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ı, farklı bir sınıfı döndürüp döndürmediğine veya istisna atıp atmadığına bakılmaksızın gerçekleşir. Platform bu tür istisnaları sessizce yoksayar.

Dikkat: Platformun Android 8.0'den (API düzeyi 26) önceki sürümlerinde bu varsayımları ihlal etmek, aynı sınıfın birden çok kez tanımlanmasına, sınıf karışıklığı nedeniyle yığın bozulmasına ve istenmeyen diğer etkilere neden olabilir.