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
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 birIllegalStateException
hatası atıyor. - Yeni
Context.startForegroundService()
yöntemi, bir ön plan hizmetini başlatır. Sistem, uygulamaların arka plandayken bileContext.startForegroundService()
çağrısı yapmasına izin verir. Ancak uygulama, hizmet oluşturulduktan sonraki beş saniye içinde bu hizmetinstartForeground()
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ındakirequestPinShortcut()
yöntemini kullanarak bir uygulama kısayolu oluşturmalısınız. ACTION_CREATE_SHORTCUT
intent artıkShortcutManager
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 veACTION_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ıkShortcutManager
'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 birNullPointerException
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ıkView
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ızView
öğesini içeren düzen XML dosyasındaandroid:defaultFocusHighlightEnabled
özelliğinifalse
olarak ayarlayın veya uygulamanızın kullanıcı arayüzü mantıkındakisetDefaultFocusHighlightEnabled()
öğesinefalse
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ıkfalse
değerini döndürüyor. Daha önce bu yöntem bunun yerinetrue
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ıkfalse
değerini döndürüyor. Daha önce bu yöntem, form veri içerdiğindetrue
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ıyorsaView
öğesini geçersiz kılın.performAccessibilityAction()
- Erişilebilirlik hizmetleri artık uygulamanızın
TextView
nesnelerindeki tümClickableSpan
ö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 önceContent-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ğerinihttp://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:
- Eski
INSTALL_NON_MARKET_APPS
ayarının değeri artık her zaman 1'dir. Bilinmeyen bir kaynağın paket yükleyiciyi kullanarak uygulama yükleyip yükleyemeyeceğini belirlemek içincanRequestPackageInstalls()
değerinin döndürdüğü değeri kullanmanız gerekir. setSecureSetting()
kullanarakINSTALL_NON_MARKET_APPS
değerini değiştirmeye çalışırsanız birUnsupportedOperationException
atılır. Kullanıcıların bilinmeyen kaynaklar kullanarak bilinmeyen uygulamaları yüklemesini engellemek için bunun yerineDISALLOW_INSTALL_UNKNOWN_SOURCES
kullanıcı kısıtlamasını uygulamanız gerekir.-
Android 8.0 (API düzeyi 26) çalıştıran cihazlarda oluşturulan yönetilen profillerde
DISALLOW_INSTALL_UNKNOWN_SOURCES
kullanıcı kısıtlaması otomatik olarak etkinleştirilir. Android 8.0'a yükseltilen cihazlardaki mevcut yönetilen profillerde, profil sahibiINSTALL_NON_MARKET_APPS
ayarını 1 yaparak (yeni sürüme geçmeden önce) bu kısıtlamayı açıkça devre dışı bırakmadıysaDISALLOW_INSTALL_UNKNOWN_SOURCES
kullanıcı kısıtlaması otomatik olarak etkinleştirilir.
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.
-
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
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.UncaughtExceptionHandler
uygulamaları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 hemsomeMethod(View)
hem desomeMethod(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. HerWebView
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
venet.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çinNetworkRequest
veyaNetworkCallback
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 yeniBuild.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ş profilindeykenLauncherApps
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 genellikleonAudioFocusChange()
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çinstreamType
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:
- 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.
- Ö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.
- Uygulamanın medya oturumu sonlandırıldıysa sistem, medya düğmesi etkinliğini uygulamanın
MediaButtonReceiver
'ine (varsa) gönderir. - 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ınCollections.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ızsort()
değerini geçersiz kılmaktan kaçınmalısınız.Bir üst sınıf
sort()
'ü uygunsuz bir şekilde uygularsaList.sort()
'üList.toArray()
,Arrays.sort()
veListIterator.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ızsort()
yöntemini geçersiz kılmak yerine bu yöntemesortCompat()
gibi benzersiz bir ad verin.-
Collections.sort()
artıksort()
ç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, birArrayList
üzerinde iterasyon gerçekleştirip iterasyonun ortasındasort()
çağrılırsa sıralamaList.sort()
çağrılarak yapılmışsa birConcurrentModificationException
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.