Bersama fitur dan kemampuan baru, Android 8.0 (API level 26) menyertakan berbagai macam perubahan sistem dan perilaku API. Dokumen ini menyoroti beberapa perubahan penting yang harus Anda pahami dan perhitungkan dalam aplikasi Anda.
Sebagian besar perubahan ini memengaruhi semua aplikasi, apa pun versi Android yang ditargetkan. Namun, beberapa perubahan hanya memengaruhi aplikasi yang menargetkan Android 8.0. Agar lebih jelas, halaman ini dibagi menjadi dua bagian: Perubahan untuk semua aplikasi dan Perubahan untuk aplikasi yang menargetkan Android 8.0.
Perubahan untuk semua aplikasi
Perubahan perilaku ini berlaku untuk
Batas eksekusi latar belakang
Sebagai salah satu perubahan yang diperkenalkan oleh Android 8.0 (API level 26) untuk meningkatkan masa pakai baterai, saat aplikasi memasuki status di-cache, tanpa komponen aktif, sistem akan melepaskan semua wakelock yang disimpan aplikasi.
Selain itu, untuk meningkatkan performa perangkat, sistem membatasi perilaku tertentu oleh aplikasi yang tidak berjalan di latar depan. Khususnya:
- Aplikasi yang berjalan di latar belakang kini memiliki batas pada seberapa bebas aplikasi dapat mengakses layanan latar belakang.
- Aplikasi tidak dapat menggunakan manifesnya untuk mendaftar ke sebagian besar siaran implisit (yaitu, siaran yang tidak ditargetkan khusus di aplikasi).
Secara default, pembatasan ini hanya berlaku pada aplikasi yang menargetkan O. Namun, pengguna dapat mengaktifkan pembatasan ini untuk aplikasi apa pun dari layar Settings, meskipun aplikasi belum menargetkan O.
Android 8.0 (API level 26) juga menyertakan perubahan berikut pada metode tertentu:
- Metode
startService()
kini menampilkanIllegalStateException
jika aplikasi yang menargetkan Android 8.0 mencoba menggunakan metode tersebut dalam situasi saat tidak diizinkan untuk membuat layanan latar belakang. - Metode
Context.startForegroundService()
baru memulai layanan latar depan. Sistem memungkinkan aplikasi memanggilContext.startForegroundService()
bahkan saat aplikasi berada di latar belakang. Namun, aplikasi harus memanggil metodestartForeground()
layanan tersebut dalam waktu lima detik setelah layanan dibuat.
Untuk mengetahui informasi selengkapnya, lihat Batas Eksekusi Latar Belakang.
Batas lokasi latar belakang Android
Untuk menghemat baterai, pengalaman pengguna, dan kesehatan sistem, aplikasi latar belakang akan semakin jarang menerima update lokasi saat digunakan pada perangkat yang menjalankan Android 8.0. Perubahan perilaku ini memengaruhi semua aplikasi yang menerima pembaruan lokasi, termasuk layanan Google Play.
Perubahan ini memengaruhi API berikut:
- Fused Location Provider (FLP)
- Pembatasan Wilayah
- Pengukuran GNSS
- Pengelola Lokasi
- Pengelola Wi-Fi
Untuk memastikan aplikasi Anda berjalan seperti yang diharapkan, lakukan langkah-langkah berikut:
- Tinjau logika aplikasi dan pastikan Anda menggunakan API lokasi terbaru.
- Uji apakah aplikasi Anda menunjukkan perilaku yang diharapkan untuk setiap kasus penggunaan.
- Pertimbangkan penggunaan Fused Location Provider (FLP) atau pembatasan wilayah untuk menangani kasus penggunaan yang bergantung pada lokasi pengguna saat ini.
Untuk mengetahui informasi selengkapnya tentang perubahan ini, lihat Batas Lokasi Latar Belakang.
Pintasan aplikasi
Android 8.0 (API level 26) menyertakan perubahan berikut pada pintasan aplikasi:
- Siaran
com.android.launcher.action.INSTALL_SHORTCUT
tidak lagi memiliki pengaruh pada aplikasi Anda, karena sekarang menjadi siaran implisit pribadi. Sebagai gantinya, Anda harus membuat pintasan aplikasi dengan menggunakan metoderequestPinShortcut()
dari classShortcutManager
. - Intent
ACTION_CREATE_SHORTCUT
kini dapat membuat pintasan aplikasi yang Anda kelola menggunakan classShortcutManager
. Intent ini juga dapat membuat pintasan peluncur lama yang tidak berinteraksi denganShortcutManager
. Sebelumnya, intent ini hanya dapat membuat pintasan peluncur lama. - Pintasan yang dibuat menggunakan
requestPinShortcut()
dan pintasan yang dibuat dalam aktivitas yang menangani intentACTION_CREATE_SHORTCUT
kini menjadi pintasan aplikasi yang lengkap. Hasilnya, aplikasi kini dapat memperbaruinya menggunakan metode diShortcutManager
. - Pintasan lama tetap mempertahankan fungsionalitasnya dari versi Android sebelumnya, tetapi Anda harus mengonversinya menjadi pintasan aplikasi secara manual di aplikasi Anda.
Untuk mempelajari lebih lanjut perubahan pada pintasan aplikasi, lihat panduan fitur Penyematan Pintasan dan Widget.
Lokal dan internasionalisasi
Android 7.0 (API level 24) memperkenalkan konsep kemampuan untuk
menentukan Local Kategori default, tetapi beberapa API terus menggunakan
metode Locale.getDefault()
generik, tanpa argumen, padahal API tersebut seharusnya menggunakan Lokal kategori DISPLAY
default. Di Android 8.0 (API level 26), metode berikut kini menggunakan Locale.getDefault(Category.DISPLAY)
, bukan Locale.getDefault()
:
Locale.getDisplayScript(Locale)
juga
akan kembali ke Locale.getDefault()
jika
nilai displayScript yang ditentukan untuk argumen
Locale
tidak tersedia.
Perubahan yang terkait lokal dan internasionalisasi tambahan adalah sebagai berikut:
- Memanggil
Currency.getDisplayName(null)
akan menampilkanNullPointerException
, yang sesuai dengan perilaku yang didokumentasikan. - Parsing nama zona waktu telah berubah. Sebelumnya,
perangkat Android menggunakan nilai jam sistem yang diambil pada waktu
booting untuk membuat cache nama zona waktu yang digunakan untuk mem-parse waktu
tanggal. Akibatnya, penguraian dapat terpengaruh negatif jika jam sistem salah pada waktu booting atau dalam kasus langka lainnya.
Sekarang, dalam kasus umum, logika penguraian menggunakan ICU dan nilai jam sistem saat ini saat mengurai nama zona waktu. Perubahan ini memberikan hasil yang lebih tepat, yang mungkin berbeda dengan versi Android sebelumnya saat aplikasi Anda menggunakan class seperti
SimpleDateFormat
. - Android 8.0 (API level 26) mengupdate versi ICU ke versi 58.
Jendela pemberitahuan
Jika aplikasi menggunakan izin SYSTEM_ALERT_WINDOW
dan menggunakan salah satu jenis jendela berikut untuk mencoba menampilkan
jendela pemberitahuan di atas aplikasi lain dan jendela sistem:
...maka jendela ini akan selalu tampak di bawah jendela yang menggunakan
jenis jendela
TYPE_APPLICATION_OVERLAY
. Jika menargetkan Android 8.0 (API level 26), aplikasi akan menggunakan
jenis jendela
TYPE_APPLICATION_OVERLAY
untuk menampilkan jendela pemberitahuan.
Untuk informasi selengkapnya, lihat bagian Tipe jendela umum untuk jendela pemberitahuan dalam perubahan perilaku untuk Aplikasi yang menargetkan Android 8.0.
Masukan dan navigasi
Dengan kehadiran aplikasi Android di ChromeOS dan faktor bentuk besar lainnya, seperti tablet, kita melihat adanya kebangkitan penggunaan navigasi keyboard dalam aplikasi Android. Dalam Android 8.0 (level API 26), kami telah menangani ulang penggunaan keyboard sebagai perangkat input navigasi, sehingga menghasilkan model yang lebih andal dan dapat diprediksi untuk navigasi berbasis panah dan tab.
Secara khusus, kami telah melakukan perubahan berikut pada perilaku fokus elemen:
-
Jika Anda belum menentukan warna status fokus apa pun untuk objek
View
(baik drawable latar depan maupun latar belakangnya), framework kini menetapkan warna sorotan fokus default untukView
. Penandaan fokus ini adalah sumber daya dapat digambar berupa riak yang didasarkan pada tema aktivitas.Jika Anda tidak ingin objek
View
menggunakan sorotan default ini saat menerima fokus, tetapkan atributandroid:defaultFocusHighlightEnabled
kefalse
dalam file XML tata letak yang berisiView
, atau teruskanfalse
kesetDefaultFocusHighlightEnabled()
dalam logika UI aplikasi Anda. - Untuk menguji pengaruh input keyboard terhadap fokus elemen UI, Anda dapat mengaktifkan opsi developer Drawing > Show layout bounds. Di Android 8.0, opsi ini menampilkan ikon "X" di atas elemen yang saat ini memiliki fokus.
Selain itu, semua elemen toolbar di Android 8.0 secara otomatis menjadi cluster navigasi keyboard, sehingga memudahkan pengguna untuk membuka atau menutup setiap toolbar sebagai satu kesatuan.
Untuk mempelajari lebih lanjut cara meningkatkan dukungan untuk navigasi keyboard dalam aplikasi Anda, baca panduan Mendukung Navigasi Keyboard.
Formulir web dan isiotomatis
Setelah Framework
Isi Otomatis Android menyediakan dukungan bawaan untuk fungsi isi otomatis, metode berikut yang terkait dengan objek WebView
telah berubah
untuk aplikasi yang diinstal di perangkat yang menjalankan Android 8.0 (API level 26):
WebSettings
-
- Metode
getSaveFormData()
kini menampilkanfalse
. Sebelumnya, metode ini menampilkantrue
. - Memanggil
setSaveFormData()
tidak lagi memiliki efek apa pun.
- Metode
WebViewDatabase
-
- Memanggil
clearFormData()
tidak lagi memiliki efek apa pun. - Metode
hasFormData()
kini menampilkanfalse
. Sebelumnya, metode ini menampilkantrue
saat formulir berisi data.
- Memanggil
Aksesibilitas
Android 8.0 (API level 26) menyertakan perubahan aksesibilitas berikut:
-
Framework aksesibilitas kini mengonversi semua gestur ketuk dua kali menjadi tindakan
ACTION_CLICK
. Perubahan ini memungkinkan TalkBack berperilaku lebih seperti layanan aksesibilitas lainnya.Jika objek
View
aplikasi Anda menggunakan penanganan sentuhan kustom, Anda harus memverifikasi bahwa objek tersebut masih berfungsi dengan TalkBack. Anda mungkin hanya perlu mendaftarkan pengendali klik yang digunakan objekView
. Jika TalkBack masih tidak mengenali gestur yang dilakukan pada objekView
ini, gantiperformAccessibilityAction()
. - Layanan aksesibilitas kini mengetahui semua instance
ClickableSpan
dalam objekTextView
aplikasi Anda.
Untuk mempelajari cara membuat aplikasi lebih mudah diakses, lihat Aksesibilitas.
Jaringan dan konektivitas HTTP(S)
Android 8.0 (API level 26) menyertakan perubahan perilaku berikut pada jaringan dan konektivitas HTTP(S):
- Permintaan OPTIONS tanpa isi memiliki header
Content-Length: 0
. Sebelumnya, header ini tidak memiliki headerContent-Length
. - HttpURLConnection menormalisasi URL yang berisi jalur kosong dengan menambahkan garis miring setelah host atau nama otoritas dengan garis miring. Misalnya, class ini
mengonversi
http://example.com
menjadihttp://example.com/
. - Pemilih proxy kustom yang ditetapkan melalui ProxySelector.setDefault() hanya menargetkan alamat (skema, host, dan port) URL yang diminta. Sebagai hasilnya, pemilihan proxy hanya bisa berdasarkan nilai-nilai itu. URL yang diteruskan ke pemilih proxy kustom tidak menyertakan jalur, parameter kueri, atau fragmen URL yang diminta.
- URI tidak boleh berisi label kosong.
Sebelumnya, platform mendukung solusi untuk menerima label kosong di nama host, yang merupakan penggunaan URI yang tidak sah. Solusi ini digunakan untuk kompatibilitas dengan rilis libcore lama. Developer yang menggunakan API dengan tidak benar akan melihat pesan ADB: "URI example..com has empty labels in the hostname. This is malformed and will not be accepted in future Android releases." Android 8.0 menghapus solusi ini; sistem menampilkan null untuk URI yang formatnya salah.
- Implementasi HttpsURLConnection Android 8.0 tidak melakukan penggantian versi protokol TLS/SSL yang tidak aman.
- Penanganan koneksi HTTP(S) tunneling telah berubah seperti berikut:
- Saat melakukan tunneling koneksi HTTPS melalui koneksi, sistem akan menempatkan nomor port (:443) dengan benar di baris Host saat mengirimkan informasi ini ke server perantara. Sebelumnya, nomor port hanya ditampilkan di baris CONNECT.
- Sistem tidak lagi mengirimkan header user-agent dan proxy-authorization dari permintaan yang disalurkan ke server proxy.
Sistem tidak lagi mengirimkan header proxy-authorization pada Http(s)URLConnection yang disalurkan ke proxy saat menyiapkan tunnel. Sebagai gantinya, sistem akan menghasilkan header proxy-authorization, dan mengirimkannya ke proxy saat proxy tersebut mengirimkan HTTP 407 sebagai respons terhadap permintaan awal.
Demikian pula, sistem tidak lagi menyalin header user-agent dari permintaan yang disalurkan ke permintaan proxy yang menyiapkan tunnel. Sebagai gantinya, library akan menghasilkan header user-agent untuk permintaan tersebut.
- Metode
send(java.net.DatagramPacket)
akan menampilkan SocketException jika metode connect() yang dieksekusi sebelumnya gagal.- DatagramSocket.connect() menyetel pendingSocketException jika ada error internal. Sebelum Android 8.0, panggilan recv() berikutnya melontarkan SocketException meskipun panggilan send() kemungkinan akan berhasil. Agar konsisten, kedua panggilan sekarang melontarkan SocketException.
- InetAddress.isReachable() mencoba ICMP sebelum beralih kembali ke protokol
Echo TCP.
- Beberapa host yang memblokir port 7 (TCP Echo), seperti google.com, sekarang mungkin dapat diakses jika menerima protokol ICMP Echo.
- Untuk host yang benar-benar tidak bisa diakses, perubahan ini berarti jumlah waktu yang dihabiskan sebelum panggilan dikembalikan akan bertambah dua kali lipat.
Bluetooth
Android 8.0 (API level 26) membuat perubahan berikut pada panjang
data yang diambil oleh metode
ScanRecord.getBytes()
:
- Metode
getBytes()
tidak membuat asumsi tentang jumlah byte yang diterima. Oleh karena itu, aplikasi tidak boleh bergantung pada jumlah byte minimum atau maksimum yang ditampilkan. Sebagai gantinya, metode ini harus mengevaluasi panjang array yang dihasilkan. - Perangkat yang kompatibel dengan Bluetooth 5 mungkin menampilkan panjang data yang melebihi maksimum ~60 byte sebelumnya.
- Jika perangkat jarak jauh tidak memberikan respons pemindaian, kurang dari 60 byte mungkin akan dikembalikan juga.
Konektivitas Mulus
Android 8.0 (API level 26) melakukan sejumlah peningkatan pada Wi-Fi Settings guna memudahkannya memilih jaringan Wi-Fi yang menawarkan pengalaman pengguna terbaik. Perubahan spesifik meliputi:
- Peningkatan stabilitas dan reliabilitas.
- UI yang lebih mudah dibaca secara intuitif.
- Menu Wi-Fi Preferences tunggal yang terkonsolidasi.
- Pada perangkat yang kompatibel, aktivasi otomatis Wi-Fi bila ada di sekitar jaringan tersimpan berkualitas tinggi.
Keamanan
Android 8.0 menyertakan perubahan terkait keamanan berikut:
- Platform tidak lagi mendukung SSLv3.
- Saat membuat koneksi HTTPS ke server yang salah menerapkan negosiasi versi protokol TLS,
HttpsURLConnection
tidak lagi mencoba solusi berupa fallback ke versi protokol TLS yang lebih lama dan mencoba lagi. - Android 8.0 (API level 26) menerapkan filter Secure Computing (SECCOMP) ke semua aplikasi. Daftar syscall yang diizinkan dibatasi untuk syscall yang diekspos melalui bionic. Meskipun ada beberapa syscall lain yang disediakan untuk kompatibilitas mundur, sebaiknya jangan gunakan syscall tersebut.
- Objek
WebView
aplikasi Anda kini berjalan dalam mode multiproses. Konten web ditangani dalam proses terisolasi yang terpisah dari proses aplikasi yang mencakupnya untuk meningkatkan keamanan. -
Anda tidak lagi dapat berasumsi bahwa APK berada di direktori yang namanya diakhiri dengan -1 atau -2. Aplikasi harus menggunakan
sourceDir
untuk mendapatkan direktori, dan tidak bergantung pada format direktori secara langsung. - Untuk informasi tentang peningkatan keamanan terkait penggunaan library native, lihat Library Native.
Selain itu, Android 8.0 (API level 26) memperkenalkan perubahan berikut yang terkait dengan penginstalan aplikasi tidak dikenal dari sumber tidak dikenal:
- Nilai setelan lama
INSTALL_NON_MARKET_APPS
kini selalu 1. Untuk menentukan apakah sumber tidak dikenal dapat menginstal aplikasi menggunakan penginstal paket, Anda harus menggunakan nilai yang ditampilkancanRequestPackageInstalls()
. - Jika Anda mencoba mengubah nilai
INSTALL_NON_MARKET_APPS
menggunakansetSecureSetting()
,UnsupportedOperationException
akan ditampilkan. Untuk mencegah pengguna menginstal aplikasi yang tidak dikenal menggunakan sumber yang tidak dikenal, Anda harus menerapkan batasan penggunaDISALLOW_INSTALL_UNKNOWN_SOURCES
. -
Profil terkelola yang dibuat di perangkat yang menjalankan Android 8.0 (API level 26) secara otomatis mengaktifkan
batasan pengguna
DISALLOW_INSTALL_UNKNOWN_SOURCES
. Untuk profil terkelola yang ada di perangkat yang diupgrade ke Android 8.0, batasan penggunaDISALLOW_INSTALL_UNKNOWN_SOURCES
diaktifkan secara otomatis, kecuali jika pemilik profil telah secara eksplisit menonaktifkan batasan ini (sebelum mengupgrade) dengan menetapkanINSTALL_NON_MARKET_APPS
ke 1.
Untuk mengetahui detail tambahan tentang menginstal aplikasi tidak dikenal, lihat panduan Izin Penginstalan Aplikasi Tidak Dikenal.
Untuk panduan tambahan mengenai pembuatan aplikasi yang lebih aman, lihat Keamanan untuk Developer Android.
Privasi
Android 8.0 (API level 26) melakukan perubahan terkait privasi berikut pada platform.
- Platform kini menangani identifier secara berbeda.
-
Untuk aplikasi yang diinstal sebelum OTA ke versi
Android 8.0 (API level 26)
(API level 26), nilai
ANDROID_ID
tetap sama kecuali jika di-uninstal, lalu diinstal ulang setelah OTA. Untuk mempertahankan nilai pada proses uninstal setelah OTA, developer dapat mengaitkan nilai lama dan baru dengan menggunakan Key/Value Backup. - Untuk aplikasi yang diinstal di perangkat yang menjalankan Android 8.0, nilai
ANDROID_ID
kini dicakup per kunci penandatanganan aplikasi, serta per pengguna. NilaiANDROID_ID
bersifat unik untuk setiap kombinasi kunci penandatanganan aplikasi, pengguna, dan perangkat. Akibatnya, aplikasi dengan kunci penandatanganan berbeda yang berjalan di perangkat yang sama tidak lagi melihat ID Android yang sama (bahkan untuk pengguna yang sama). - Nilai
ANDROID_ID
tidak berubah saat uninstal atau instal ulang paket, selama kunci penandatanganan sama (dan aplikasi tidak diinstal sebelum OTA ke versi Android 8.0). - Nilai
ANDROID_ID
tidak berubah meskipun update sistem menyebabkan kunci penandatanganan paket berubah. - Di perangkat yang dikirimkan dengan layanan Google Play dan ID Iklan,
Anda harus menggunakan
ID Iklan. Sebagai sistem sederhana dan standar untuk memonetisasi aplikasi, ID Iklan adalah ID unik yang dapat direset oleh pengguna untuk iklan. Layanan ini disediakan
oleh layanan Google Play.
Produsen perangkat lainnya harus terus menyediakan
ANDROID_ID
.
-
Untuk aplikasi yang diinstal sebelum OTA ke versi
Android 8.0 (API level 26)
(API level 26), nilai
- Kueri properti sistem
net.hostname
menghasilkan hasil null.
Pencatatan log atas pengecualian yang tidak tertangkap
Jika aplikasi menginstal Thread.UncaughtExceptionHandler
yang
tidak memanggil ke Thread.UncaughtExceptionHandler
default,
sistem
tidak akan mematikan aplikasi saat terjadi pengecualian yang tidak tertangkap. Mulai dari
Android 8.0 (API level 26), sistem mencatat log stacktrace pengecualian dalam situasi
ini; di versi platform sebelumnya, sistem tidak akan
mencatat log stacktrace pengecualian.
Sebaiknya implementasi Thread.UncaughtExceptionHandler
kustom selalu memanggil
penangan default; aplikasi yang mengikuti rekomendasi ini tidak terpengaruh oleh
perubahan di Android 8.0.
Perubahan tanda tangan findViewById()
Semua instance metode findViewById()
sekarang menampilkan
<T extends View> T
, bukan View
. Perubahan ini
memiliki implikasi berikut:
- Perubahan ini dapat mengakibatkan kode yang telah ada memiliki jenis nilai yang ditampilkan yang ambigu, misalnya
someMethod(View)
dansomeMethod(TextView)
sama-sama ada dan mengambil hasil panggilan kefindViewById()
. - Saat menggunakan bahasa sumber Java 8, transmisi eksplisit ke
View
diperlukan jika jenis nilai yang ditampilkan tidak dibatasi (misalnya,assertNotNull(findViewById(...)).someViewMethod())
. - Penggantian metode
findViewById()
yang belum final (misalnya,Activity.findViewById()
) memerlukan pembaruan jenis nilai yang ditampilkan.
Perubahan statistik penggunaan penyedia kontak
Di Android versi sebelumnya, komponen Contacts Provider
memungkinkan developer mendapatkan data penggunaan untuk setiap kontak. Data penggunaan ini
mengekspos informasi untuk setiap alamat email dan setiap nomor telepon yang dikaitkan
dengan sebuah kontak, termasuk berapa kali kontak dihubungi
dan waktu terakhir kontak dihubungi. Aplikasi yang meminta izin
READ_CONTACTS
dapat membaca data ini.
Aplikasi masih dapat membaca data ini jika meminta
izin
READ_CONTACTS
. Di Android 8.0 (API level 26) dan yang lebih tinggi, kueri untuk data penggunaan menampilkan
perkiraan, bukan nilai persis. Sistem Android mempertahankan
nilai persisnya secara internal, sehingga perubahan ini tidak memengaruhi
API pelengkapan otomatis.
Perubahan perilaku ini memengaruhi parameter kueri berikut:
Penanganan kumpulan
AbstractCollection.removeAll()
dan AbstractCollection.retainAll()
kini selalu menampilkan NullPointerException
; sebelumnya, NullPointerException
tidak ditampilkan saat koleksi
kosong. Perubahan ini menjadikan perilaku konsisten dengan dokumentasi.
Android enterprise
Android 8.0 (API level 26) mengubah perilaku beberapa API dan fitur untuk aplikasi perusahaan, termasuk pengontrol kebijakan perangkat (DPC). Perubahan tersebut meliputi:
- Perilaku baru untuk membantu aplikasi mendukung profil kerja pada perangkat yang sepenuhnya dikelola.
- Perubahan pada penanganan update sistem, verifikasi aplikasi, dan autentikasi untuk meningkatkan integritas sistem dan perangkat.
- Peningkatan pada pengalaman pengguna untuk penyediaan, notifikasi, layar Terbaru, dan VPN yang selalu aktif.
Untuk melihat semua perubahan enterprise di Android 8.0 (API level 26) dan mempelajari caranya memengaruhi aplikasi Anda, baca Android di Enterprise.
Aplikasi yang menargetkan Android 8.0
Perubahan perilaku ini berlaku secara eksklusif pada aplikasi yang menargetkan
Android 8.0 (API level 26) atau yang lebih baru. Aplikasi yang dikompilasi untuk Android 8.0,
atau menetapkan targetSdkVersion
ke Android 8.0 atau yang lebih tinggi harus memodifikasi
aplikasinya untuk mendukung perilaku ini dengan benar, jika memungkinkan pada aplikasi.
Jendela pemberitahuan
Aplikasi yang menggunakan izin SYSTEM_ALERT_WINDOW
tidak dapat lagi menggunakan jenis jendela berikut untuk menampilkan jendela pemberitahuan
di atas aplikasi lain dan jendela sistem:
Sebagai gantinya, aplikasi harus menggunakan jenis jendela baru yang disebut
TYPE_APPLICATION_OVERLAY
.
Saat menggunakan
jenis jendela
TYPE_APPLICATION_OVERLAY
untuk menampilkan jendela pemberitahuan aplikasi Anda, perhatikan karakteristik
jenis jendela baru berikut:
- Jendela pemberitahuan aplikasi selalu muncul pada jendela sistem yang kritis, seperti status bar dan IME.
- Sistem dapat memindahkan atau mengubah ukuran jendela yang menggunakan
jenis jendela
TYPE_APPLICATION_OVERLAY
untuk meningkatkan presentasi layar. - Dengan membuka menu notifikasi, pengguna dapat mengakses setelan untuk memblokir
aplikasi agar tidak menampilkan jendela pemberitahuan yang ditampilkan menggunakan
jenis jendela
TYPE_APPLICATION_OVERLAY
.
Notifikasi perubahan konten
Android 8.0 (API level 26) mengubah perilaku
ContentResolver.notifyChange()
dan registerContentObserver(Uri, boolean, ContentObserver)
untuk aplikasi yang menargetkan Android 8.0.
Semua API ini sekarang mengharuskan ContentProvider
yang valid didefinisikan untuk otoritas di semua URI. Penentuan ContentProvider
yang valid dengan izin yang relevan akan
membantu melindungi aplikasi Anda dari perubahan konten akibat aplikasi berbahaya, dan mencegah
Anda membocorkan data yang mungkin bersifat pribadi ke aplikasi berbahaya.
Fokus tampilan
Objek View
yang dapat diklik kini juga dapat difokuskan secara
default. Jika Anda ingin objek View
dapat diklik, tetapi tidak
dapat difokuskan, tetapkan
atribut
android:focusable
ke false
dalam file XML
tata letak yang berisi View
, atau teruskan false
ke setFocusable()
dalam logika UI
aplikasi Anda.
Pencocokan agen pengguna dalam deteksi browser
Android 8.0 (level API 26) dan yang lebih baru menyertakan string ID build OPR
. Beberapa kecocokan pola dapat
menyebabkan logika deteksi browser salah mengidentifikasi browser non-Opera sebagai Opera.
Contoh kecocokan pola tersebut mungkin:
if(p.match(/OPR/)){k="Opera";c=p.match(/OPR\/(\d+.\d+)/);n=new Ext.Version(c[1])}
Untuk menghindari masalah yang timbul dari kesalahan identifikasi tersebut, gunakan string selain
OPR
sebagai pencocokan pola untuk browser Opera.
Keamanan
Perubahan berikut memengaruhi keamanan di Android 8.0 (API level 26):
- Jika konfigurasi keamanan jaringan aplikasi Anda memilih untuk tidak ikut mendukung traffic cleartext, objek
WebView
aplikasi Anda tidak dapat mengakses situs melalui HTTP. Sebagai gantinya, setiap objekWebView
harus menggunakan HTTPS. - Setelan sistem Izinkan sumber tidak dikenal telah dihapus; sebagai gantinya, izin Instal aplikasi yang tidak dikenal akan mengelola penginstalan aplikasi yang tidak dikenal dari sumber tidak dikenal. Untuk mempelajari izin baru ini lebih lanjut, lihat panduan Izin Penginstalan Aplikasi Tidak Dikenal.
Untuk panduan tambahan tentang cara meningkatkan keamanan aplikasi Anda, lihat Keamanan untuk Developer Android.
Akses akun dan visibilitas
Di Android 8.0 (API level 26), aplikasi tidak dapat lagi mendapatkan akses
ke akun pengguna kecuali jika pengautentikasi memiliki akun tersebut atau
pengguna memberikan akses tersebut. Izin
GET_ACCOUNTS
tidak lagi memadai. Agar diberi akses ke akun, aplikasi harus
menggunakan AccountManager.newChooseAccountIntent()
atau metode khusus
autentikasi. Setelah mendapatkan akses ke akun, aplikasi dapat memanggil
AccountManager.getAccounts()
untuk mengaksesnya.
Android 8.0 menghentikan LOGIN_ACCOUNTS_CHANGED_ACTION
. Sebagai gantinya, aplikasi
harus menggunakan
addOnAccountsUpdatedListener()
untuk mendapatkan pembaruan tentang akun selama runtime.
Untuk informasi tentang API dan metode baru yang ditambahkan untuk akses akun dan visibilitas, lihat Akses Akun dan Visibilitas di bagian API Baru dalam dokumen ini.
Privasi
Perubahan berikut memengaruhi privasi di Android 8.0 (API level 26).
-
Properti sistem
net.dns1
,net.dns2
,net.dns3
, dannet.dns4
tidak lagi tersedia, sebuah perubahan yang meningkatkan privasi di platform. -
Untuk mendapatkan informasi jaringan seperti server DNS, aplikasi dengan
izin
ACCESS_NETWORK_STATE
dapat mendaftarkan objekNetworkRequest
atauNetworkCallback
. Kelas ini tersedia di Android 5.0 (API level 21) dan yang lebih tinggi. -
Build.SERIAL tidak digunakan lagi.
Aplikasi yang perlu mengetahui nomor seri hardware harus
menggunakan metode
Build.getSerial()
baru, yang memerlukan izinREAD_PHONE_STATE
. -
LauncherApps
API tidak lagi mengizinkan aplikasi profil kerja untuk mendapatkan informasi tentang profil utama. Saat pengguna berada dalam profil kerja,LauncherApps
API berperilaku seolah-olah tidak ada aplikasi yang diinstal di profil lain dalam grup profil yang sama. Seperti sebelumnya, upaya untuk mengakses profil yang tidak berkaitan akan menyebabkan SecurityExceptions.
Izin
Sebelum Android 8.0 (API level 26), jika aplikasi meminta izin pada waktu proses dan izin diberikan, sistem juga salah memberikan izin lain kepada aplikasi yang berada di grup izin yang sama, dan yang didaftarkan dalam manifes.
Untuk aplikasi yang menargetkan Android 8.0, perilaku ini telah dikoreksi. Aplikasi hanya diberikan izin yang telah dimintanya secara eksplisit. Namun, setelah pengguna memberikan izin ke aplikasi, semua permintaan izin berikutnya dalam grup izin tersebut akan diberikan secara otomatis.
Misalnya, aplikasi mencantumkan READ_EXTERNAL_STORAGE
dan
WRITE_EXTERNAL_STORAGE
dalam manifesnya.
Aplikasi meminta READ_EXTERNAL_STORAGE
dan
pengguna memberikannya. Jika aplikasi menargetkan API level 25 atau yang lebih rendah, sistem juga
akan memberikan WRITE_EXTERNAL_STORAGE
pada saat
yang sama, karena aplikasi tersebut termasuk dalam grup izin STORAGE
yang sama dan juga
terdaftar dalam manifes. Jika aplikasi menargetkan Android 8.0 (API level 26), sistem hanya akan memberikan
READ_EXTERNAL_STORAGE
pada waktu itu;
tetapi, jika aplikasi nanti meminta WRITE_EXTERNAL_STORAGE
, sistem akan langsung
memberikan hak istimewa tersebut tanpa meminta konfirmasi pengguna.
Media
- Framework ini dapat menjalankan pengecilan audio otomatis dengan sendirinya. Dalam hal ini, saat aplikasi lain meminta fokus dengan
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
, aplikasi yang memiliki fokus akan mengurangi volumenya, tetapi biasanya tidak menerima callbackonAudioFocusChange()
dan tidak akan kehilangan fokus audio. API baru tersedia untuk mengganti perilaku ini bagi aplikasi yang perlu menjeda, bukan menurunkan volume. - Saat pengguna menerima panggilan telepon, streaming media yang aktif akan dibisukan selama panggilan tersebut.
- Semua API terkait audio harus menggunakan
AudioAttributes
bukan jenis streaming audio untuk menjelaskan kasus penggunaan pemutaran audio. Terus menggunakan tipe streaming audio hanya untuk kontrol volume. Penggunaan jenis aliran data lainnya masih berfungsi (misalnya, argumenstreamType
ke konstruktorAudioTrack
yang tidak digunakan lagi), tetapi sistem mencatat hal ini sebagai error. - Saat menggunakan
AudioTrack
, jika aplikasi meminta buffering audio yang cukup besar, framework akan mencoba menggunakan output buffering yang dalam jika tersedia. - Di Android 8.0 (API level 26), penanganan peristiwa tombol media berbeda:
- Penanganan tombol media dalam aktivitas UI tidak berubah: aktivitas latar depan masih mendapatkan prioritas dalam menangani peristiwa tombol media.
- Jika aktivitas latar depan tidak menangani peristiwa tombol media, sistem akan merutekan peristiwa ke aplikasi yang terakhir memutar audio secara lokal. Status aktif, flag, dan status pemutaran sesi media tidak dipertimbangkan saat menentukan aplikasi mana yang menerima peristiwa tombol media.
- Jika sesi media aplikasi telah dirilis,
sistem akan mengirimkan peristiwa tombol media ke
MediaButtonReceiver
aplikasi jika ada. - Untuk setiap kasus lainnya, sistem menghapus kejadian tombol media.
Library native
Dalam aplikasi yang menargetkan Android 8.0 (API level 26), library native tidak lagi dimuat jika berisi segmen muatan apa pun yang dapat ditulisi dan dieksekusi. Beberapa aplikasi mungkin berhenti berfungsi karena perubahan ini jika memiliki library native dengan segmen pemuatan yang salah. Ini adalah tindakan pengetatan keamanan.
Untuk informasi selengkapnya, lihat Segmen yang Dapat Ditulisi dan Dieksekusi.
Perubahan linker dikaitkan ke API level yang ditargetkan aplikasi. Jika ada perubahan linker pada API level yang ditargetkan, aplikasi tidak dapat memuat library. Jika Anda menargetkan level API yang lebih rendah dari level API tempat perubahan linker terjadi, logcat akan menampilkan peringatan.
Penanganan kumpulan
Di Android 8.0 (API level 26),
Collections.sort()
diterapkan di
atas List.sort()
. Sebaliknya
berlaku di Android 7.x (API level 24 dan 25):
Implementasi default List.sort()
disebut Collections.sort()
.
Perubahan ini memungkinkan Collections.sort()
memanfaatkan implementasi List.sort()
yang dioptimalkan, tetapi memiliki batasan berikut:
Implementasi
List.sort()
tidak boleh memanggilCollections.sort()
, karena hal itu akan mengakibatkan stack overflow akibat rekursi tanpa batas. Sebagai gantinya, jika Anda ingin perilaku default dalam implementasiList
, sebaiknya jangan menggantisort()
.Jika class induk menerapkan
sort()
dengan tidak benar, biasanya tidak mengapa untuk menggantiList.sort()
dengan implementasi yang dibuat di atasList.toArray()
,Arrays.sort()
, danListIterator.set()
. Contoh:@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); } }
Biasanya, Anda juga dapat mengganti
List.sort()
dengan penerapan yang didelegasikan ke implementasi default yang berbeda, bergantung pada API level. Contoh:@Override public void sort(Comparator<? super E> comparator) { if (Build.VERSION.SDK_INT <= 25) { Collections.sort(this); } else { super.sort(comparator); } }
Jika Anda melakukan opsi yang kedua hanya karena ingin metode
sort()
tersedia di semua level API, pertimbangkan untuk memberinya nama yang unik, sepertisortCompat()
, alih-alih menggantisort()
.-
Collections.sort()
kini dianggap sebagai perubahan struktural dalam penerapan List yang memanggilsort()
. Misalnya, di versi platform sebelum Android 8.0 (API level 26), melakukan iterasi padaArrayList
dan memanggilsort()
di dalamnya di tengah proses iterasi akan menampilkanConcurrentModificationException
jika pengurutan dilakukan dengan memanggilList.sort()
.Collections.sort()
tidak menampilkan pengecualian.Perubahan ini membuat perilaku platform lebih konsisten: Setiap pendekatan kini menghasilkan
ConcurrentModificationException
.
Perilaku pemuatan kelas
Android 8.0 (API level 26) memeriksa untuk memastikan loader class tidak
merusak asumsi runtime saat memuat class baru. Pemeriksaan ini
dilakukan untuk mengetahui apakah class tersebut direferensikan dari Java (dari
forName()
),
byte Dalvik, atau JNI. Platform tidak mencegat panggilan langsung dari Java ke
metode loadClass()
, maupun memeriksa
hasil panggilan tersebut. Perilaku ini tidak boleh memengaruhi fungsi loader class
yang berperilaku baik.
Platform akan memeriksa apakah deskriptor class yang ditampilkan oleh loader class
sesuai dengan deskriptor yang diharapkan. Jika deskriptor yang ditampilkan tidak cocok,
platform akan menampilkan error NoClassDefFoundError
, dan menyimpan pesan detail yang menunjukkan perbedaan tersebut dalam
pengecualian.
Platform juga akan memeriksa apakah deskriptor kelas yang diminta memang valid. Pemeriksaan
ini akan menangkap panggilan JNI yang secara tidak langsung memuat class seperti GetFieldID()
,
dengan meneruskan deskriptor tidak valid ke class tersebut. Misalnya, kolom dengan tanda tangan
java/lang/String
tidak ditemukan karena tanda tangan tersebut tidak valid;
seharusnya Ljava/lang/String;
.
Hal ini berbeda dengan panggilan JNI ke FindClass()
dengan java/lang/String
adalah nama yang sepenuhnya memenuhi syarat.
Android 8.0 (API level 26) tidak mendukung beberapa loader class yang mencoba menentukan class
menggunakan objek DexFile yang sama. Upaya untuk melakukannya menyebabkan runtime Android menampilkan error
InternalError
dengan pesan "Attempt to register dex file <filename>
with multiple class loaders".
DexFile API sekarang tidak digunakan lagi, dan Anda sangat disarankan untuk menggunakan
salah satu classloader platform, termasuk PathClassLoader
atau
BaseDexClassLoader
, sebagai gantinya.
Catatan: Anda dapat membuat beberapa loader class yang mereferensikan
penampung file APK atau JAR yang sama dari sistem file. Biasanya, hal ini tidak
mengakibatkan overhead memori yang besar: Jika file DEX dalam penampung disimpan, bukan
dikompresi, platform dapat melakukan operasi mmap
pada file tersebut, bukan
mengekstraknya secara langsung. Namun, jika platform harus mengekstrak file DEX dari container,
mereferensikan file DEX dengan cara ini dapat menghabiskan banyak memori.
Di Android, semua loader kelas dianggap berkemampuan sejajar. Jika beberapa thread berlomba memuat class yang sama dengan loader class yang sama, thread pertama yang akan menyelesaikan operasi akan menang, dan hasilnya akan digunakan untuk thread lainnya. Perilaku ini terjadi terlepas apakah loader class telah menampilkan class yang sama, menampilkan class yang berbeda, atau menampilkan pengecualian. Platform secara diam-diam mengabaikan pengecualian semacam ini.
Perhatian: Di platform dengan versi lebih rendah dari Android 8.0 (API level 26), melanggar asumsi ini dapat menyebabkan pendefinisian class yang sama beberapa kali, kerusakan heap karena kebingungan class, dan efek-efek yang tidak diinginkan lainnya.