Bersama dengan fitur dan kemampuan baru, Android 8.0 (level API 26) mencakup berbagai perubahan perilaku sistem dan API. Dokumen ini menyoroti beberapa perubahan penting yang harus Anda pahami dan perhitungkan di aplikasi Anda.
Sebagian besar perubahan ini memengaruhi semua aplikasi, apa pun versi Android yang mereka targetkan. Namun, beberapa perubahan hanya memengaruhi penargetan aplikasi Android 8.0. Untuk memaksimalkan kejelasan, dibagi menjadi dua bagian: Perubahan untuk semua aplikasi dan Perubahan untuk penargetan aplikasi 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) meningkatkan daya tahan baterai, saat aplikasi memasuki di-cache status, tanpa status komponen, sistem melepaskan setiap wakelock yang ditahan aplikasi.
Selain itu, untuk meningkatkan kinerja perangkat, sistem membatasi beberapa perilaku aplikasi yang tidak berjalan di latar depan. Khususnya:
- Aplikasi yang berjalan di latar belakang kini memiliki batasan seberapa bebas mereka dapat mengakses layanan latar belakang.
- Aplikasi tidak dapat menggunakan manifesnya untuk mendaftar ke sebagian besar siaran implisit (yaitu, siaran yang tidak ditargetkan secara khusus pada 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, bahkan jika aplikasi tersebut belum menargetkan O.
Android 8.0 (API level 26) juga menyertakan perubahan berikut untuk metode tertentu:
- Metode
startService()
kini menampilkanIllegalStateException
jika aplikasi yang menargetkan Android 8.0 akan mencoba menggunakan metode tersebut dalam situasi ketika tidak diizinkan untuk membuat layanan latar belakang. - Metode
Context.startForegroundService()
baru memulai layanan latar depan. Sistem mengizinkan aplikasi untuk memanggilContext.startForegroundService()
bahkan saat aplikasi di latar belakang. Namun, aplikasi harus memanggil metodestartForeground()
layanan tersebut dalam waktu lima detik setelah layanan dibuat.
Untuk informasi selengkapnya, lihat Batas Eksekusi Latar Belakang.
Batas lokasi latar belakang Android
Untuk menghemat baterai, pengalaman pengguna, dan kesehatan sistem, aplikasi latar belakang lebih jarang menerima pembaruan lokasi saat digunakan di perangkat 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 lokasi terbaru Google Cloud Platform.
- Menguji apakah aplikasi menunjukkan perilaku yang diharapkan untuk setiap penggunaan ini masalahnya atau bukan.
- Pertimbangkan untuk menggunakan Menyatu Penyedia Lokasi (FLP) atau pembatasan wilayah untuk menangani kasus penggunaan yang bergantung pada lokasi pengguna saat ini.
Untuk informasi selengkapnya tentang perubahan ini, lihat Lokasi Latar Belakang Batas.
Pintasan aplikasi
Android 8.0 (API level 26) menyertakan perubahan berikut untuk pintasan aplikasi:
- Nomor siaran
com.android.launcher.action.INSTALL_SHORTCUT
lagi memiliki pengaruh pada aplikasi Anda, karena sekarang menjadi implisit, . Sebagai gantinya, Anda harus membuat pintasan aplikasi menggunakanrequestPinShortcut()
dari classShortcutManager
. ACTION_CREATE_SHORTCUT
sekarang bisa membuat pintasan aplikasi yang Anda kelola menggunakan ClassShortcutManager
. Intent ini juga bisa membuat pintasan peluncur lama yang tidak berinteraksi denganShortcutManager
. Sebelumnya, intent ini dapat membuat pintasan peluncur lama saja.- Pintasan yang dibuat menggunakan
requestPinShortcut()
dan pintasan yang dibuat dalam aktivitas yang menanganiACTION_CREATE_SHORTCUT
sekarang menjadi pintasan aplikasi yang lengkap. Akibatnya, aplikasi kini dapat mengupdatenya menggunakan metode diShortcutManager
. - Pintasan lama tetap mempertahankan fungsinya dari versi sebelumnya Android, tetapi Anda harus mengonversinya menjadi pintasan aplikasi secara manual di aplikasi Anda.
Untuk mempelajari lebih lanjut perubahan pada pintasan aplikasi, lihat Penyematan Pintasan dan Panduan fitur widget.
Lokal dan internasionalisasi
Android 7.0 (API level 24)
memperkenalkan konsep kemampuan
menentukan Lokalitas Kategori default, tetapi beberapa API terus menggunakan
Locale.getDefault()
umum
, tanpa argumen, padahal seharusnya menggunakan Lokal kategori DISPLAY
default. Di Android 8.0 (API level 26),
metode berikut sekarang menggunakan Locale.getDefault(Category.DISPLAY)
bukan Locale.getDefault()
:
Locale.getDisplayScript(Locale)
juga
akan kembali ke Locale.getDefault()
saat
Nilai displayScript ditentukan untuk Locale
tidak tersedia.
Perubahan lokal dan terkait internasionalisasi tambahan adalah berikut ini:
- Memanggil
Currency.getDisplayName(null)
akan menampilkanNullPointerException
, sesuai dengan perilaku yang didokumentasikan. - Parsing nama zona waktu telah berubah. Sebelumnya,
Perangkat Android menggunakan nilai jam sistem yang diambil sampelnya saat booting
waktu untuk meng-cache nama zona waktu yang digunakan untuk mengurai tanggal
kali. Akibatnya, penguraian dapat terdampak secara negatif jika sistem
jam itu salah pada saat {i>booting<i} atau
dalam kasus lain yang lebih jarang.
Sekarang, dalam kasus yang umum, logika penguraian menggunakan ICU dan nilai jam sistem saat ini saat mengurai nama zona waktu. Ini perubahan memberikan hasil yang lebih tepat, yang mungkin berbeda dari hasil sebelumnya Versi Android saat aplikasi Anda menggunakan class seperti
SimpleDateFormat
. - Android 8.0 (API level 26) mengupdate versi ICU ke versi 58.
Jendela pemberitahuan
Jika aplikasi menggunakan SYSTEM_ALERT_WINDOW
izin akses internal dan menggunakan salah satu
tipe jendela berikut untuk mencoba menampilkan
jendela peringatan di atas jendela aplikasi dan sistem lain:
...maka jendela ini akan selalu muncul di bawah jendela yang menggunakan
Jendela TYPE_APPLICATION_OVERLAY
. Jika aplikasi menargetkan Android 8.0 (API level 26), aplikasi akan menggunakan
TYPE_APPLICATION_OVERLAY
untuk menampilkan jendela pemberitahuan.
Untuk informasi selengkapnya, lihat Jenis jendela umum untuk bagian jendela pemberitahuan dalam perubahan perilaku untuk Aplikasi yang menargetkan Android 8.0.
Masukan dan navigasi
Dengan hadirnya aplikasi Android di ChromeOS dan faktor bentuk besar lainnya, seperti tablet, kita melihat kebangkitan penggunaan navigasi {i>keyboard<i} di dalam Android. Dalam Android 8.0 (API level 26), kami telah membahas kembali menggunakan {i>keyboard<i} sebagai perangkat input navigasi, sehingga menghasilkan pengalaman yang lebih dapat diandalkan, yang dapat diprediksi untuk navigasi berbasis panah dan tab.
Secara khusus, kami telah membuat perubahan berikut pada fokus elemen perilaku:
-
Jika Anda belum menentukan warna status fokus apa pun untuk Objek
View
(baik latar depan maupun latar belakangnya drawable), framework sekarang menetapkan warna sorotan fokus default untukView
. Sorotan fokus ini adalah drawable riak yang berdasarkan tema aktivitas.Jika Anda tidak ingin objek
View
menggunakan default ini menyorotinya saat menerima fokus, aturandroid:defaultFocusHighlightEnabled
kefalse
dalam file XML tata letak yang berisi elemenView
, atau teruskanfalse
kesetDefaultFocusHighlightEnabled()
di logika UI aplikasi Anda. - Untuk menguji bagaimana input keyboard memengaruhi fokus elemen UI, Anda dapat mengaktifkan Gambar > Tampilkan batas tata letak opsi developer. Di Android 8.0, opsi ini menampilkan "X" di atas elemen yang saat ini memiliki fokus.
Selain itu, semua elemen toolbar di Android 8.0 secara otomatis cluster navigasi keyboard, memudahkan pengguna untuk menavigasi ke dan dari setiap {i>toolbar<i} keseluruhan.
Untuk mempelajari lebih lanjut cara meningkatkan dukungan untuk navigasi keyboard dalam aplikasi Anda, baca dokumentasi Pendukung Panduan Navigasi Keyboard.
Formulir web dan isiotomatis
Setelah tombol Isi Otomatis Android
Framework 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
-
- Tujuan
getSaveFormData()
sekarang menampilkanfalse
. Sebelumnya, metode ini menampilkan Sebagai gantinya,true
. - Menelepon
setSaveFormData()
tidak lama akan berdampak apa pun.
- Tujuan
WebViewDatabase
-
- Menelepon
clearFormData()
tidak lama akan berdampak apa pun. - Tujuan
hasFormData()
metode sekarang menampilkanfalse
. Sebelumnya, metode ini menampilkantrue
saat formulir berisi data.
- Menelepon
Aksesibilitas
Android 8.0 (level API 26) menyertakan perubahan aksesibilitas berikut:
-
Framework aksesibilitas sekarang mengonversi semua gestur ketuk dua kali menjadi
ACTION_CLICK
tindakan. Perubahan ini memungkinkan TalkBack berperilaku lebih seperti aksesibilitas.Jika objek
View
aplikasi Anda menggunakan sentuhan kustom Anda harus memverifikasi bahwa pesan tersebut masih berfungsi dengan TalkBack. Anda mungkin hanya perlu mendaftarkan pengendali klik yangView
digunakan oleh objek. Jika TalkBack masih tidak mengenali gestur yang dilakukan padaView
objek, penggantianperformAccessibilityAction()
. - Layanan aksesibilitas kini menyadari semua
ClickableSpan
instance dalam aplikasi AndaTextView
objek.
Untuk mempelajari lebih lanjut cara membuat aplikasi Anda lebih mudah diakses, lihat Aksesibilitas.
Jaringan dan konektivitas HTTP(S)
Android 8.0 (API level 26) menyertakan perubahan perilaku berikut untuk jaringan dan konektivitas HTTP(S):
- Permintaan OPTIONS tanpa isi memiliki
Content-Length: 0
{i>header<i}. Sebelumnya, header ini tidak memiliki headerContent-Length
. - HttpURLConnection menormalkan URL yang berisi jalur kosong dengan menambahkan
garis miring setelah {i>host<i} atau
nama otoritas dengan garis miring. Sebagai contoh,
mengonversi
http://example.com
menjadihttp://example.com/
. - Pemilih proxy kustom yang disetel melalui ProxySelector.setDefault() hanya menargetkan alamat (skema, host, dan port) dari URL yang diminta. Sebagai hasilnya, pemilihan proxy hanya bisa berdasarkan nilai-nilai itu. URL yang diteruskan ke pemilih proxy khusus tidak menyertakan URL yang diminta jalur, parameter kueri, atau fragmen.
- URI tidak boleh berisi label kosong.
Sebelumnya, platform mendukung solusi untuk menerima label kosong di nama host, yang merupakan penggunaan URI ilegal. Solusi ini ditujukan untuk kompatibilitas dengan rilis libcore lama. Developer yang menggunakan API salah akan melihat pesan ADB: "URI example..com memiliki label kosong di nama {i>host-<i}nya. Format ini salah dan tidak akan diterima pada Android mendatang rilis." Android 8.0 menghapus solusi ini; sistem mengembalikan null untuk URI dengan format yang salah.
- Implementasi HttpsURLConnection Android 8.0 tidak melakukan penggantian versi protokol TLS/SSL yang tidak aman.
- Penanganan koneksi HTTP(S) tunneling telah berubah sebagai berikut:
- Ketika tunneling koneksi HTTPS melalui koneksi, sistem menempatkan nomor port (:443) dengan benar di baris Host saat mengirim informasi ini ke server perantara. Sebelumnya, porta angka hanya muncul di baris CONNECT.
- Sistem tidak lagi mengirimkan agen pengguna dan otorisasi proxy
header dari permintaan yang disalurkan ke server proxy.
Sistem tidak lagi mengirimkan header proxy-otorisasi pada Http(s)URLConnection yang disalurkan ke proxy saat menyiapkan . Sebagai gantinya, sistem akan menghasilkan {i>header<i} {i>proxy<i}, dan mengirimkannya ke {i>proxy<i} ketika {i>proxy<i} itu mengirim HTTP 407 sebagai respons terhadap permintaan awal.
Demikian pula, sistem tidak lagi menyalin {i>header<i} agen pengguna dari permintaan yang disalurkan ke permintaan proxy yang menyiapkan . Sebagai gantinya, pustaka itu akan menghasilkan header agen pengguna untuk itu permintaan.
send(java.net.DatagramPacket)
akan memunculkan SocketException jika connect() yang dieksekusi sebelumnya gagal.- DatagramSocket.connect() menyetel pendingSocketException jika ada error internal. Sebelum Android 8.0, perintah recv() berikutnya pemunculan SocketException, meskipun panggilan send() akan berhasil. Agar konsisten, kedua panggilan sekarang melontarkan SocketException.
- InetAddress.isReachable() mencoba melakukan ICMP sebelum beralih kembali ke TCP Echo
dan berperforma tinggi
karena merupakan protokol biner.
- Beberapa {i>host<i} yang memblokir port 7 (TCP Echo), seperti google.com, dapat sekarang dapat dijangkau jika mereka menerima protokol ICMP Echo.
- Untuk {i>host<i} yang benar-benar tidak dapat dijangkau, perubahan ini berarti bahwa jumlah {i>2 kali lipat waktu yang dihabiskan sebelum panggilan itu kembali.
Bluetooth
Android 8.0 (API level 26) membuat perubahan berikut pada panjang
data yang ScanRecord.getBytes()
akan mengambil:
- Metode
getBytes()
tidak membuat asumsi untuk jumlah byte yang diterima. Oleh karena itu, aplikasi tidak boleh bergantung pada byte minimum atau maksimum yang ditampilkan. Sebaliknya, mereka harus mengevaluasi panjang {i>array<i} yang dihasilkan. - Perangkat yang kompatibel dengan Bluetooth 5 mungkin mengembalikan panjang data yang melebihi sebelumnya maksimum ~60 byte.
- Jika perangkat jarak jauh tidak memberikan respons pemindaian, kurang dari 60 byte mungkin juga dikembalikan.
Konektivitas Mulus
Android 8.0 (API level 26) membuat sejumlah peningkatan pada Setelan Wi-Fi agar lebih mudah untuk 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 saat jaringan tersimpan berkualitas tinggi berada di dekat Anda.
Keamanan
Android 8.0 menyertakan hal-hal berikut yang terkait dengan keamanan perubahan:
- Platform tidak lagi mendukung SSLv3.
- Saat membuat koneksi HTTPS ke server yang salah
menerapkan negosiasi versi protokol TLS,
HttpsURLConnection
tidak lagi mencoba solusi tersebut untuk mengembalikan ke versi protokol TLS sebelumnya dan mencoba lagi. - Android 8.0 (API level 26) menerapkan Secure Computing (SECCOMP) filter ke semua aplikasi. Daftar syscall yang diizinkan dibatasi untuk yang terekspos melalui bionik. Meskipun ada beberapa {i>syscall<i} lain yang disediakan untuk kompatibilitas mundur, kami merekomendasikan untuk tidak menggunakannya.
- Objek
WebView
aplikasi Anda kini berjalan dalam multiproses mode. Konten web ditangani dalam proses yang terpisah dan terisolasi dari yang berisi proses aplikasi untuk meningkatkan keamanan. -
Anda tidak lagi dapat berasumsi bahwa APK berada di direktori yang namanya diakhiri
di -1 atau -2. Aplikasi yang harus digunakan
sourceDir
untuk mendapatkan direktori, dan tidak bergantung pada format direktori secara langsung. - Untuk informasi tentang peningkatan keamanan terkait penggunaan library, 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 menjadi selalu 1. Untuk menentukan apakah sumber yang tidak dikenal dapat menginstal aplikasi menggunakan {i>installer<i} paket tersebut, Anda harus menggunakan nilai yang akan ditampilkancanRequestPackageInstalls()
. - Jika Anda mencoba
mengubah nilai
INSTALL_NON_MARKET_APPS
menggunakansetSecureSetting()
,UnsupportedOperationException
ditampilkan. Untuk mencegah pengguna menginstal aplikasi tidak dikenal menggunakan aplikasi yang tidak dikenal sumber, Anda harus menerapkan PenggunaDISALLOW_INSTALL_UNKNOWN_SOURCES
resource. -
Profil terkelola yang dibuat di perangkat yang menjalankan Android 8.0 (API level 26) secara otomatis memiliki
Pengguna
DISALLOW_INSTALL_UNKNOWN_SOURCES
mengaktifkan pembatasan. Untuk profil terkelola yang sudah ada pada perangkat dengan diupgrade ke Android 8.0, PenggunaDISALLOW_INSTALL_UNKNOWN_SOURCES
pembatasan otomatis diaktifkan kecuali pemilik profil secara eksplisit menonaktifkan batasan ini (sebelum meningkatkan versi) dengan menyetelINSTALL_NON_MARKET_APPS
menjadi 1.
Untuk detail tambahan tentang cara menginstal aplikasi yang tidak dikenal, lihat Aplikasi Tidak Dikenal Panduan Izin Instal.
Untuk panduan tambahan tentang cara membuat aplikasi lebih aman, lihat Keamanan untuk Developer Android.
Privasi
Android 8.0 (level API 26) membuat hal berikut ini terkait privasi perubahan pada platform.
- Platform kini menangani identifier secara berbeda.
-
Untuk aplikasi yang diinstal sebelum OTA ke versi
Android 8.0 (level API 26)
(API level 26), nilai
ANDROID_ID
tetap sama kecuali jika di-uninstal dan kemudian diinstal ulang setelah OTA. Untuk mempertahankan nilai di seluruh menghapus instalan setelah OTA, pengembang dapat menghubungkan nilai lama dan baru menggunakan Key/Value Backup. - Untuk aplikasi yang diinstal pada perangkat yang menjalankan Android 8.0, nilai
ANDROID_ID
kini tercakup per kunci penandatanganan aplikasi, serta per pengguna. Nilai dariANDROID_ID
unik untuk setiap kombinasi kunci penandatanganan aplikasi, pengguna, dan perangkat. Akibatnya, aplikasi dengan kunci penandatanganan berbeda 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 Android 8.0). - Nilai
ANDROID_ID
tidak berubah meskipun pembaruan sistem menyebabkan kunci penandatanganan paket berubah. - Pada perangkat yang dikirim dengan layanan Google Play dan ID Iklan,
kamu harus pake
ID Iklan. Sistem sederhana dan standar untuk memonetisasi aplikasi,
ID Iklan adalah ID unik yang dapat direset oleh pengguna untuk iklan. Tersedia
oleh layanan Google Play.
Produsen perangkat lain harus melanjutkan untuk menyediakan
ANDROID_ID
.
-
Untuk aplikasi yang diinstal sebelum OTA ke versi
Android 8.0 (level API 26)
(API level 26), nilai
- Membuat kueri properti sistem
net.hostname
menghasilkan null hasil pengujian tersebut.
Pencatatan log atas pengecualian yang tidak tertangkap
Jika aplikasi menginstal Thread.UncaughtExceptionHandler
yang
tidak memanggil Thread.UncaughtExceptionHandler
default,
sistem melakukan
tidak mematikan aplikasi bila terjadi pengecualian yang tidak tertangkap. Mulai dari
Android 8.0 (API level 26), sistem akan mencatat log stacktrace pengecualian dalam
situasi ini; dalam versi platform sebelumnya, sistem tidak akan memiliki
mencatat stacktrace pengecualian.
Sebaiknya Thread.UncaughtExceptionHandler
kustom
implementasinya selalu memanggil
pengendali 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:
- Hal ini dapat menyebabkan kode yang sudah ada memiliki
jenis nilai yang ditampilkan yang ambigu,
misalnya jika ada
someMethod(View)
dansomeMethod(TextView)
yang menerima hasil panggilan kefindViewById()
. - Saat menggunakan bahasa sumber Java 8, diperlukan transmisi eksplisit ke
View
jika jenis nilai yang ditampilkan tidak dibatasi (misalnya,assertNotNull(findViewById(...)).someViewMethod())
. - Penggantian metode
findViewById()
yang belum final (untuk misalnya,Activity.findViewById()
) akan memerlukan hasil yang ditampilkan jenisnya diperbarui.
Perubahan statistik penggunaan penyedia kontak
Di versi Android sebelumnya, komponen Penyedia Kontak
memungkinkan developer mendapatkan data penggunaan untuk setiap kontak. Data penggunaan ini
mengekspos informasi untuk setiap alamat email dan setiap nomor telepon yang terkait
dengan kontak, termasuk berapa kali kontak tersebut telah dihubungi
dan terakhir kali kontak dihubungi. Aplikasi yang meminta
READ_CONTACTS
dapat membaca data ini.
Aplikasi masih dapat membaca data ini jika meminta
READ_CONTACTS
izin akses. Di Android 8.0 (API level 26) dan yang lebih tinggi, kueri untuk data penggunaan ditampilkan
nilai perkiraan dan bukan nilai tepatnya. Sistem Android mengelola
nilai yang tepat secara internal, sehingga perubahan ini tidak memengaruhi
API pelengkapan otomatis.
Perubahan perilaku ini memengaruhi parameter kueri berikut:
Penanganan kumpulan
AbstractCollection.removeAll()
dan AbstractCollection.retainAll()
sekarang selalu tampilkan 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 perangkat pengontrol kebijakan (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 perangkat dan sistem.
- Peningkatan pada pengalaman pengguna untuk penyediaan, notifikasi, Layar terbaru, dan VPN yang selalu aktif.
Untuk melihat semua perubahan perusahaan di Android 8.0 (level API 26) dan mempelajari caranya memengaruhi aplikasi Anda, baca Android di Perusahaan.
Aplikasi yang menargetkan Android 8.0
Perubahan perilaku ini berlaku khusus bagi aplikasi yang menargetkan
Android 8.0 (level API 26) atau yang lebih tinggi. Aplikasi yang dikompilasi untuk Android 8.0,
atau menyetel targetSdkVersion
ke Android 8.0 atau yang lebih tinggi harus mengubah
aplikasi mereka untuk mendukung perilaku ini dengan benar, jika memungkinkan pada aplikasi.
Jendela pemberitahuan
Aplikasi yang menggunakan SYSTEM_ALERT_WINDOW
izin 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
Jendela TYPE_APPLICATION_OVERLAY
untuk menampilkan jendela pemberitahuan aplikasi Anda, pertahankan karakteristik berikut
jenis jendela baru dengan mempertimbangkan:
- Jendela peringatan aplikasi selalu muncul di bawah jendela sistem penting, seperti sebagai status bar dan IME.
- Sistem dapat memindahkan atau mengubah ukuran jendela yang menggunakan
TYPE_APPLICATION_OVERLAY
jenis jendela untuk meningkatkan presentasi layar. - Dengan membuka menu notifikasi, pengguna dapat mengakses pengaturan untuk memblokir
aplikasi agar tidak menampilkan jendela peringatan yang ditampilkan menggunakan
TYPE_APPLICATION_OVERLAY
jenis jendela.
Notifikasi perubahan konten
Android 8.0 (API level 26) mengubah cara
ContentResolver.notifyChange()
dan registerContentObserver(Uri, boolean, ContentObserver)
untuk aplikasi yang menargetkan Android 8.0.
API ini sekarang mengharuskan ContentProvider
yang valid
ditetapkan untuk otoritas di semua URI. Menentukan ContentProvider
yang valid dengan izin yang relevan akan
membantu melindungi aplikasi Anda dari perubahan konten akibat aplikasi berbahaya, dan mencegah Anda
membocorkan data yang berpotensi
pribadi ke aplikasi berbahaya.
Fokus tampilan
Objek View
yang dapat diklik kini juga dapat difokuskan oleh
secara default. Jika Anda ingin objek View
dapat diklik, tetapi tidak
dapat difokuskan, mengatur
android:focusable
ke false
dalam tata letak
File XML yang berisi View
, atau teruskan false
ke setFocusable()
di UI aplikasi
logika.
Pencocokan agen pengguna dalam deteksi browser
Android 8.0 (API level 26) dan yang lebih tinggi menyertakan
string ID build OPR
. Beberapa pola yang cocok mungkin
menyebabkan logika deteksi browser salah mengidentifikasi browser non-Opera sebagai Opera.
Contoh kecocokan pola tersebut adalah:
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 pola yang cocok untuk browser Opera.
Keamanan
Perubahan berikut memengaruhi keamanan di Android 8.0 (API level 26):
- Jika konfigurasi keamanan jaringan aplikasi Anda
memilih
untuk mendukung traffic cleartext, aplikasi Anda
Objek
WebView
tidak dapat mengakses situs melalui HTTP. Masing-masing Sebagai gantinya, objekWebView
harus menggunakan HTTPS. - Setelan sistem Izinkan sumber tidak dikenal telah dihapus; dalam tempat, izin Menginstal aplikasi yang tidak dikenal mengelola penginstalan aplikasi yang tidak dikenal dari sumber tidak dikenal. Untuk mempelajari izin baru ini lebih lanjut, lihat Aplikasi Tidak Dikenal Panduan Izin Instal.
Untuk panduan tambahan tentang cara membuat aplikasi lebih aman, lihat Keamanan untuk Developer Android.
Akses akun dan visibilitas
Di Android 8.0 (API level 26), aplikasi tidak lagi mendapatkan akses
ke akun pengguna kecuali otentikator
memiliki akun atau
memberikan akses tersebut. Tujuan
Izin GET_ACCOUNTS
tidak lagi memadai. Agar diberi akses ke akun, aplikasi harus
gunakan AccountManager.newChooseAccountIntent()
atau khusus pengautentikasi
. Setelah mendapatkan akses ke akun, aplikasi dapat memanggil
AccountManager.getAccounts()
untuk mengaksesnya.
Android 8.0 tidak digunakan lagi
LOGIN_ACCOUNTS_CHANGED_ACTION
. Aplikasi
sebaiknya gunakan
addOnAccountsUpdatedListener()
untuk mendapatkan info terbaru 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 perubahan yang meningkatkan privasi di platform ini. -
Untuk mendapatkan informasi jaringan seperti server DNS, aplikasi dengan
ACCESS_NETWORK_STATE
izin akses dapat mendaftarkanNetworkRequest
atau ObjekNetworkCallback
. 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 seharusnya
gunakan metode
Build.getSerial()
baru, yang memerlukanREAD_PHONE_STATE
izin akses. -
LauncherApps
API tidak lagi mengizinkan profil kerja aplikasi untuk mendapatkan informasi tentang profil utama. Saat pengguna sedang melakukan pekerjaan profil,LauncherApps
API berperilaku seolah-olah tidak ada aplikasi diinstal di profil lain dalam grup profil yang sama. Seperti sebelumnya, upaya untuk mengakses profil yang tidak terkait akan menyebabkan SecurityException.
Izin
Sebelum Android 8.0 (API level 26), jika aplikasi meminta izin saat runtime dan izin diberikan, sistem juga salah memberi aplikasi izin lainnya yang dimiliki oleh akun izin akses yang berbeda, dan yang terdaftar di manifes.
Untuk aplikasi yang menargetkan Android 8.0, perilaku ini telah dikoreksi. Aplikasi hanya diberi izin yang secara eksplisit dimilikinya diminta. Namun, setelah pengguna memberikan izin ke aplikasi, semua permintaan izin berikutnya dalam grup izin tersebut diberikan secara otomatis.
Misalnya, sebuah 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
memberi WRITE_EXTERNAL_STORAGE
secara bersamaan
waktu, karena izin akses tersebut berada di grup izin STORAGE
yang sama dan juga
terdaftar di manifes. Jika aplikasi menargetkan Android 8.0 (API level 26), sistem akan memberikan
hanya READ_EXTERNAL_STORAGE
pada saat itu;
tetapi, jika aplikasi nanti meminta WRITE_EXTERNAL_STORAGE
, sistem akan segera
memberikan hak istimewa tersebut
tanpa meminta izin pengguna.
Media
- Kerangka kerja ini dapat melakukan
pengecilan audio otomatis
dengan sendirinya. Dalam hal ini, ketika aplikasi lain meminta fokus dengan
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
, aplikasi yang memiliki fokus mengurangi volumenya tetapi biasanya tidak menerimaonAudioFocusChange()
dan tidak akan kehilangan fokus audio. API baru tersedia untuk mengganti perilaku ini untuk aplikasi yang perlu berhenti sejenak. - Saat pengguna menjawab panggilan telepon, streaming media yang aktif akan dibisukan selama durasi panggilan telepon.
- 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 streaming lainnya masih berfungsi (misalnya, argumenstreamType
ke versi yang tidak digunakan lagi konstruktorAudioTrack
), tetapi sistem mencatat ini sebagai {i>error<i}. - Saat menggunakan
AudioTrack
, jika aplikasi akan meminta buffer audio yang cukup besar, framework akan mencoba menggunakan {i>output <i} dalam {i>buffer <i}jika tersedia. - Di Android 8.0 (API level 26), penanganan peristiwa tombol media berbeda:
- Penanganan tombol media dalam aktivitas UI belum 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 tersebut ke aplikasi yang terakhir memutar audio secara lokal. Status aktif, flag, dan pemutaran status sesi media tidak dipertimbangkan saat menentukan aplikasi mana yang menerima media peristiwa tombol.
- Jika sesi media aplikasi telah dirilis,
sistem mengirim kejadian tombol media ke elemen
MediaButtonReceiver
jika ada. - Untuk setiap kasus lainnya, sistem menghapus kejadian tombol media.
Library native
Di aplikasi yang menargetkan Android 8.0 (API level 26), library native tidak pemuatan yang lebih lama jika berisi segmen muatan yang dapat ditulisi dan file yang dapat dieksekusi. Beberapa aplikasi mungkin berhenti berfungsi karena perubahan ini jika mereka library native dengan segmen pemuatan yang salah. Ini adalah sebagai langkah hardening keamanan.
Untuk informasi selengkapnya, lihat Segmen yang Dapat Ditulis dan yang Dapat Dieksekusi.
Perubahan linker dikaitkan ke API level yang ditargetkan aplikasi. Jika ada adalah perubahan penaut di level API yang ditargetkan, aplikasi tidak bisa memuat library tersebut. Jika Anda menargetkan level API yang lebih rendah dari level API tempat perubahan penaut terjadi, logcat menampilkan peringatan.
Penanganan kumpulan
Di Android 8.0 (API level 26),
Collections.sort()
diimplementasikan pada
bagian atas List.sort()
. Kebalikan
benar di Android 7.x (API level 24 dan 25):
Implementasi default List.sort()
disebut Collections.sort()
.
Perubahan ini memungkinkan Collections.sort()
untuk memanfaatkan List.sort()
yang dioptimalkan
tetapi memiliki batasan berikut:
Implementasi
List.sort()
tidak boleh memanggilCollections.sort()
, karena hal itu akan mengakibatkan stack overflow karena rekursi tak terbatas. Sebaliknya, jika Anda ingin perilaku default dalam implementasiList
, sebaiknya hindari penggantiansort()
.Jika class induk menerapkan
sort()
dengan tidak benar, biasanya tidak masalah 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); } }
Dalam kebanyakan kasus, Anda juga dapat mengganti
List.sort()
dengan implementasi yang didelegasikan ke setelan default implementasi yang bergantung pada level API. 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 terakhir hanya karena ingin memiliki
sort()
yang tersedia di semua API level, pertimbangkan untuk memberinya nama yang unik, sepertisortCompat()
, bukan menggantisort()
.-
Collections.sort()
kini dihitung sebagai modifikasi struktural di Mencantumkan implementasi yang memanggilsort()
. Misalnya, dalam versi platform sebelum Android 8.0 (level API 26), melakukan iterasi melaluiArrayList
dan memanggilsort()
di dalamnya di tengah proses iterasi akan menampilkanConcurrentModificationException
apakah penyortiran telah dilakukan dengan memanggilList.sort()
.Collections.sort()
tidak memberikan pengecualian.Perubahan ini membuat perilaku platform lebih konsisten: Baik sekarang menghasilkan
ConcurrentModificationException
.
Perilaku pemuatan kelas
Android 8.0 (API level 26) memeriksa untuk memastikan bahwa loader class tidak
merusak asumsi runtime saat memuat class baru. Pemeriksaan ini
akan dijalankan tanpa melihat kelasnya
direferensikan dari Java (dari
forName()
),
Bytecode Dalvik, atau JNI. Platform tidak mencegat panggilan langsung dari Java ke
loadClass()
, serta tidak memeriksa
hasil panggilan tersebut. Perilaku ini seharusnya tidak mempengaruhi fungsi
oleh loader class ini.
Platform akan memeriksa apakah deskriptor class yang dikembalikan oleh loader class
sesuai dengan deskriptor yang diharapkan. Jika deskriptor yang dikembalikan tidak sesuai,
platform akan menampilkan error NoClassDefFoundError
, dan menyimpan
pengecualian, pesan terperinci
yang mencatat perbedaannya.
Platform juga akan memeriksa apakah deskriptor kelas yang diminta memang valid. Ini
menangkap panggilan JNI yang secara tidak langsung memuat class seperti GetFieldID()
,
meneruskan deskriptor yang tidak valid
ke kelas-kelas itu. Misalnya, kolom dengan tanda tangan
java/lang/String
tidak ditemukan karena tanda tangan itu tidak valid;
nilainya harus Ljava/lang/String;
.
Ini berbeda dengan panggilan JNI untuk FindClass()
dengan java/lang/String
adalah nama valid yang sepenuhnya memenuhi syarat.
Android 8.0 (API level 26) tidak mendukung adanya beberapa loader class, cobalah untuk menentukan class
menggunakan objek DexFile yang sama. Upaya untuk melakukannya akan menyebabkan Android runtime menampilkan
InternalError
error dengan pesan "Mencoba mendaftarkan file dex <filename>
dengan beberapa loader class".
DexFile API sekarang tidak digunakan lagi, dan Anda sangat dianjurkan untuk menggunakan
salah satu classloader platform, termasuk PathClassLoader
atau
BaseDexClassLoader
.
Catatan: Anda bisa membuat beberapa loader class yang mereferensikan
kontainer file APK atau JAR yang sama dari sistem file. Melakukan hal ini biasanya tidak
mengakibatkan banyak overhead memori: Jika file DEX dalam container disimpan,
dikompresi, platform dapat menjalankan operasi mmap
pada kode tersebut, bukan
mengekstraknya secara langsung. Akan tetapi, jika platform harus mengekstrak file DEX dari kontainer,
mereferensikan file DEX dengan cara ini bisa menghabiskan banyak memori.
Di Android, semua loader kelas dianggap berkemampuan sejajar. Saat beberapa thread berlomba memuat class yang sama dengan class yang sama loader pertama, thread pertama yang menyelesaikan operasi akan menang, dan hasilnya digunakan untuk ke thread lainnya. Perilaku ini terjadi terlepas dari apakah loader class telah menampilkan class yang sama, menampilkan class yang berbeda, atau menampilkan pengecualian. Platform secara diam-diam mengabaikan pengecualian semacam ini.
Perhatian: Dalam versi platform lebih rendah dari Android 8.0 (API level 26), merusak asumsi ini dapat mengarah pada penentuan beberapa kali, kerusakan heap akibat kebingungan class, dan efek lain yang tidak diinginkan.