Perubahan Perilaku Android 8.0

Bersama dengan fitur dan kemampuan baru, Android 8.0 (API level 26) menyertakan berbagai perubahan sistem dan perilaku API. Dokumen ini menyoroti beberapa perubahan utama yang harus Anda pahami dan perhitungkan dalam aplikasi Anda.

Sebagian besar perubahan ini memengaruhi semua aplikasi, terlepas dari 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 semua aplikasi saat dijalankan pada platform Android 8.0 (level API 26), terlepas dari level API yang ditargetkan. Semua developer harus meninjau perubahan ini dan memodifikasi aplikasi mereka untuk mendukung perubahan dengan benar, jika memungkinkan untuk aplikasi.

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 batasan terkait seberapa bebas aplikasi tersebut 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 batasan ini untuk aplikasi apa pun dari layar Settings, meskipun aplikasi tersebut tidak menargetkan O.

Android 8.0 (API level 26) juga menyertakan perubahan berikut untuk metode tertentu:

  • Metode startService() kini menampilkan IllegalStateException jika aplikasi yang menargetkan Android 8.0 mencoba menggunakan metode tersebut saat tidak diizinkan membuat layanan latar belakang.
  • Metode Context.startForegroundService() baru akan memulai layanan latar depan. Sistem memungkinkan aplikasi memanggil Context.startForegroundService() bahkan saat aplikasi berada di latar belakang. Namun, aplikasi harus memanggil metode startForeground() 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 lebih jarang menerima pembaruan lokasi jika digunakan di 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 untuk menggunakan Penyedia Lokasi Gabungan (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 untuk pintasan aplikasi:

  • Siaran com.android.launcher.action.INSTALL_SHORTCUT tidak lagi berpengaruh pada aplikasi Anda, karena sekarang menjadi siaran implisit pribadi. Sebagai gantinya, Anda harus membuat pintasan aplikasi menggunakan metode requestPinShortcut() dari class ShortcutManager.
  • Intent ACTION_CREATE_SHORTCUT kini dapat membuat pintasan aplikasi yang Anda kelola menggunakan class ShortcutManager. Intent ini juga dapat membuat pintasan peluncur lama yang tidak berinteraksi dengan ShortcutManager. Sebelumnya, intent ini hanya dapat membuat pintasan peluncur versi lama.
  • Pintasan yang dibuat menggunakan requestPinShortcut() dan pintasan yang dibuat dalam aktivitas yang menangani intent ACTION_CREATE_SHORTCUT kini menjadi pintasan aplikasi yang lengkap. Akibatnya, aplikasi kini dapat mengupdatenya menggunakan metode di ShortcutManager.
  • Pintasan lama mempertahankan fungsinya dari versi Android sebelumnya, tetapi Anda harus mengonversinya menjadi pintasan aplikasi secara manual di aplikasi Anda.

Untuk mempelajari perubahan pintasan aplikasi lebih lanjut, lihat panduan fitur Menyematkan Pintasan dan Widget.

Lokal dan internasionalisasi

Android 7.0 (API level 24) memperkenalkan konsep kemampuan untuk menentukan Lokalitas Kategori default, tetapi beberapa API terus menggunakan metode Locale.getDefault() generik, tanpa argumen, saat API tersebut seharusnya menggunakan Lokalitas kategori DISPLAY default. Di Android 8.0 (API level 26), metode berikut sekarang menggunakan Locale.getDefault(Category.DISPLAY) dan bukan Locale.getDefault():

Locale.getDisplayScript(Locale) juga kembali ke Locale.getDefault() saat nilai displayScript yang ditentukan untuk argumen Locale tidak tersedia.

Perubahan tambahan terkait lokalitas dan internasionalisasi adalah sebagai berikut:

  • Memanggil Currency.getDisplayName(null) akan menampilkan NullPointerException, yang cocok dengan perilaku yang didokumentasikan.
  • Parsing nama zona waktu telah berubah. Sebelumnya, perangkat Android menggunakan nilai jam sistem yang diambil pada waktu booting untuk meng-cache nama zona waktu yang digunakan untuk mengurai waktu tanggal. Akibatnya, penguraian dapat terkena dampak negatif jika jam sistem salah pada waktu booting atau dalam kasus lain yang jarang terjadi.

    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 notifikasi di atas jendela aplikasi dan sistem lain:

...maka jendela ini akan selalu muncul di bawah jendela yang menggunakan jenis jendela TYPE_APPLICATION_OVERLAY. Jika aplikasi menargetkan Android 8.0 (API level 26), aplikasi akan menggunakan jenis jendela TYPE_APPLICATION_OVERLAY untuk menampilkan jendela pemberitahuan.

Untuk mengetahui informasi selengkapnya, lihat bagian Jenis jendela umum untuk jendela notifikasi 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, kami melihat kebangkitan penggunaan navigasi keyboard dalam aplikasi Android. Dalam Android 8.0 (level API 26), kami telah menangani kembali 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 membuat perubahan berikut pada perilaku fokus elemen:

  • Jika Anda belum menentukan warna status fokus untuk objek View (baik drawable latar depan maupun latar belakang), framework sekarang menetapkan warna sorotan fokus default untuk View. Sorotan fokus ini adalah drawable ripple yang didasarkan pada tema aktivitas.

    Jika Anda tidak ingin objek View menggunakan sorotan default ini saat menerima fokus, tetapkan atribut android:defaultFocusHighlightEnabled ke false dalam file XML tata letak yang berisi View, atau teruskan false ke setDefaultFocusHighlightEnabled() dalam logika UI aplikasi Anda.

  • Untuk menguji pengaruh input keyboard terhadap fokus elemen UI, Anda dapat mengaktifkan opsi developer Gambar > Tampilkan batas tata letak. 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 otomatis merupakan cluster navigasi keyboard, sehingga memudahkan pengguna membuka dan keluar dari setiap toolbar secara keseluruhan.

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
WebViewDatabase
  • Memanggil clearFormData() tidak lagi berpengaruh.
  • Metode hasFormData() sekarang menampilkan false. Sebelumnya, metode ini menampilkan true saat formulir berisi data.

Aksesibilitas

Android 8.0 (API level 26) menyertakan perubahan berikut untuk aksesibilitas:

  • 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 sentuh kustom, Anda harus memverifikasi bahwa objek tersebut masih berfungsi dengan TalkBack. Anda mungkin hanya perlu mendaftarkan pengendali klik yang digunakan objek View Anda. Jika TalkBack masih tidak mengenali gestur yang dilakukan pada objek View ini, ganti performAccessibilityAction().

  • Layanan aksesibilitas kini mengetahui semua instance ClickableSpan dalam objek TextView aplikasi Anda.

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 pada jaringan dan konektivitas HTTP(S):

  • Permintaan OPTIONS tanpa isi memiliki header Content-Length: 0. Sebelumnya, permintaan tersebut tidak memiliki header Content-Length.
  • HttpURLConnection menormalisasi URL yang berisi jalur kosong dengan menambahkan garis miring setelah nama host atau otoritas dengan garis miring. Misalnya, API akan mengonversi http://example.com menjadi http://example.com/.
  • Pemilih proxy kustom yang disetel 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 fragmen, parameter kueri, atau jalur URL yang diminta.
  • URI tidak boleh berisi label kosong.

    Sebelumnya, platform mendukung solusi untuk menerima label kosong dalam nama host, yang merupakan penggunaan URI yang tidak sah. Solusi ini ditujukan untuk kompatibilitas dengan rilis libcore lama. Developer yang menggunakan API tersebut salah akan melihat pesan ADB: "URI example.com has empty labels in the hostname. Format ini salah dan tidak akan diterima dalam rilis Android mendatang." Android 8.0 menghapus solusi ini; sistem menampilkan null untuk URI yang formatnya salah.

  • Implementasi HttpsURLConnection Android 8.0 tidak menjalankan penggantian versi protokol TLS/SSL yang tidak aman.
  • Penanganan koneksi HTTP(S) tunneling telah berubah sebagai berikut:
    • Saat tunneling koneksi HTTPS melalui koneksi, sistem akan menempatkan nomor port (:443) dengan benar di baris Host saat mengirim informasi ini ke server perantara. Sebelumnya, nomor port hanya muncul di baris CONNECT.
    • Sistem tidak lagi mengirimkan header agen pengguna dan otorisasi proxy dari permintaan yang disalurkan ke server proxy.

      Sistem tidak lagi mengirimkan header proxy-Authorization pada Http(s)URLConnection yang di-tunnel ke proxy saat menyiapkan tunnel. Sebagai gantinya, sistem akan menghasilkan header otorisasi proxy, dan mengirimkannya ke proxy saat proxy tersebut mengirimkan HTTP 407 sebagai respons atas permintaan awal.

      Demikian pula, sistem tidak lagi menyalin header agen pengguna dari permintaan yang disalurkan ke permintaan proxy yang menyiapkan tunnel. Sebagai gantinya, library akan menghasilkan header agen pengguna untuk permintaan tersebut.

  • Metode send(java.net.DatagramPacket) akan menampilkan SocketException jika metode connect() yang dijalankan sebelumnya gagal.
    • DatagramSocket.connect() menetapkan pendingSocketException jika ada error internal. Sebelum Android 8.0, panggilan recv() berikutnya menampilkan SocketException, meskipun panggilan send() akan berhasil. Agar konsisten, kedua panggilan sekarang melontarkan SocketException.
  • InetAddress.isReachable() mencoba ICMP sebelum kembali ke protokol TCP Echo.
    • Beberapa host yang memblokir port 7 (TCP Echo), seperti google.com, kini dapat dijangkau jika menerima protokol ICMP Echo.
    • Untuk host yang benar-benar tidak dapat dijangkau, perubahan ini berarti dua kali jumlah waktu yang dihabiskan sebelum panggilan kembali.

Bluetooth

Android 8.0 (API level 26) membuat perubahan berikut pada panjang data yang diambil oleh metode ScanRecord.getBytes():

  • Metode getBytes() tidak membuat asumsi mengenai jumlah byte yang diterima. Oleh karena itu, aplikasi tidak boleh bergantung pada jumlah minimum atau maksimum byte yang ditampilkan. Sebaliknya, fungsi tersebut harus mengevaluasi panjang array yang dihasilkan.
  • Perangkat yang kompatibel dengan Bluetooth 5 dapat menampilkan panjang data yang melebihi batas maksimum ~60 byte sebelumnya.
  • Jika perangkat jarak jauh tidak memberikan respons pemindaian, ukuran kurang dari 60 byte juga dapat ditampilkan.

Konektivitas Mulus

Android 8.0 (API level 26) melakukan sejumlah peningkatan pada Setelan Wi-Fi untuk mempermudah pemilihan 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 sekitar.

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 yaitu kembali 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, kami tidak menyarankan penggunaannya.
  • Objek WebView aplikasi Anda kini berjalan dalam mode multiproses. Konten web ditangani dalam proses yang terpisah dan terisolasi dari proses aplikasi yang memuatnya untuk meningkatkan keamanan.
  • Anda tidak dapat lagi berasumsi bahwa APK berada di direktori yang namanya berakhir dengan -1 atau -2. Aplikasi harus menggunakan sourceDir untuk mendapatkan direktori, dan tidak mengandalkan format direktori secara langsung.
  • Untuk informasi tentang peningkatan keamanan yang terkait dengan penggunaan library native, lihat Library Native.

Selain itu, Android 8.0 (API level 26) memperkenalkan perubahan berikut yang terkait dengan penginstalan aplikasi yang tidak dikenal dari sumber tidak dikenal:

Untuk detail tambahan tentang menginstal aplikasi yang tidak dikenal, lihat panduan Izin Penginstalan Aplikasi Tidak Dikenal.

Untuk panduan tambahan tentang cara meningkatkan keamanan aplikasi, lihat Keamanan untuk Developer Android.

Privasi

Android 8.0 (API level 26) melakukan perubahan terkait privasi berikut pada platform ini.

  • Platform kini menangani identifier secara berbeda.
    • Untuk aplikasi yang diinstal sebelum OTA ke versi Android 8.0 (level API 26) (level API 26), nilai ANDROID_ID tetap sama kecuali jika di-uninstal, lalu diinstal ulang setelah OTA. Untuk mempertahankan nilai di seluruh uninstal setelah OTA, developer dapat mengaitkan nilai lama dan baru 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. Nilai ANDROID_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 dikirim dengan layanan Google Play dan ID Iklan, Anda harus menggunakan ID Iklan. Sistem yang sederhana dan standar untuk memonetisasi aplikasi, ID Iklan adalah ID unik yang dapat direset oleh pengguna untuk tujuan periklanan. Software ini disediakan oleh layanan Google Play.

      Produsen perangkat lain harus tetap menyediakan ANDROID_ID.

  • Kueri properti sistem net.hostname akan 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 menghentikan aplikasi saat pengecualian yang tidak tertangkap terjadi. Mulai Android 8.0 (level API 26), sistem mencatat stacktrace pengecualian dalam situasi ini; pada versi platform yang lebih lama, sistem tidak akan mencatat stacktrace pengecualian ke dalam log.

Sebaiknya implementasi Thread.UncaughtExceptionHandler kustom selalu memanggil pengendali default; aplikasi yang mengikuti rekomendasi ini tidak akan 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 mengakibatkan kode yang ada memiliki jenis nilai yang ditampilkan yang ambigu, misalnya jika ada someMethod(View) dan someMethod(TextView) yang mengambil hasil panggilan ke findViewById().
  • Jika bahasa sumber Java 8 digunakan, 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()) akan memerlukan pembaruan jenis nilai yang ditampilkan.

Perubahan statistik penggunaan penyedia kontak

Pada versi Android sebelumnya, komponen Penyedia Kontak memungkinkan developer mendapatkan data penggunaan untuk setiap kontak. Data penggunaan ini menampilkan informasi untuk setiap alamat email dan setiap nomor telepon yang terkait dengan suatu kontak, termasuk berapa kali kontak dihubungi dan terakhir kali kontak tersebut 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 versi lebih tinggi, kueri untuk data penggunaan menampilkan perkiraan, bukan nilai tepat. Sistem Android mempertahankan nilai tepatnya 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 perusahaan di Android 8.0 (level API 26) dan mempelajari kemungkinan perubahannya terhadap 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 versi lebih tinggi. 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 bagi aplikasi tersebut.

Jendela pemberitahuan

Aplikasi yang menggunakan izin SYSTEM_ALERT_WINDOW tidak lagi dapat 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 untuk aplikasi Anda, perhatikan karakteristik jenis jendela baru berikut:

  • Jendela peringatan aplikasi selalu muncul di bawah jendela sistem yang penting, 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 (level API 26) mengubah cara ContentResolver.notifyChange() dan registerContentObserver(Uri, boolean, ContentObserver) berperilaku untuk aplikasi yang menargetkan Android 8.0.

API ini sekarang mengharuskan ContentProvider yang valid ditentukan 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 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 (API level 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 pencocokan 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 pencocokan pola untuk browser Opera.

Keamanan

Perubahan berikut memengaruhi keamanan di Android 8.0 (API level 26):

  • Jika konfigurasi keamanan jaringan aplikasi Anda memilih tidak ikut mendukung traffic cleartext, objek WebView aplikasi Anda tidak dapat mengakses situs melalui HTTP. Sebagai gantinya, setiap objek WebView harus menggunakan HTTPS.
  • Setelan sistem Izinkan sumber tidak dikenal telah dihapus; sebagai gantinya, izin Instal aplikasi tidak dikenal 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, lihat Keamanan untuk Developer Android.

Akses akun dan visibilitas

Di Android 8.0 (API level 26), aplikasi tidak lagi bisa 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 pengautentikasi. Setelah mendapatkan akses ke akun, aplikasi dapat memanggil AccountManager.getAccounts() untuk mengaksesnya.

Android 8.0 tidak akan lagi menggunakan LOGIN_ACCOUNTS_CHANGED_ACTION. Sebagai gantinya, aplikasi harus menggunakan addOnAccountsUpdatedListener() untuk mendapatkan update 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, dan net.dns4 tidak lagi tersedia, perubahan yang meningkatkan privasi di platform.
  • Untuk mendapatkan informasi jaringan seperti server DNS, aplikasi dengan izin ACCESS_NETWORK_STATE dapat mendaftarkan objek NetworkRequest atau NetworkCallback. 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 izin READ_PHONE_STATE.
  • LauncherApps API tidak lagi memungkinkan aplikasi profil kerja mendapatkan informasi tentang profil utama. Jika pengguna berada di profil kerja, LauncherApps API akan berperilaku seolah-olah tidak ada aplikasi yang 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 pada saat runtime dan izin diberikan, sistem juga salah memberikan izin lainnya yang merupakan bagian dari grup izin yang sama dan yang telah terdaftar dalam manifes ke aplikasi tersebut.

Untuk aplikasi yang menargetkan Android 8.0, perilaku ini telah dikoreksi. Aplikasi hanya diberi izin yang telah diminta secara eksplisit. Namun, setelah pengguna memberikan izin ke aplikasi, semua permintaan izin berikutnya dalam grup izin tersebut akan otomatis diberikan.

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 di saat yang sama, karena aplikasi 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 saat itu; tetapi, jika aplikasi nanti meminta WRITE_EXTERNAL_STORAGE, sistem akan langsung memberikan hak istimewa tersebut tanpa meminta izin pengguna.

Media

  • Framework ini dapat menjalankan pengecilan volume audio otomatis sendiri. 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 callback onAudioFocusChange() dan tidak akan kehilangan fokus audio. API baru tersedia untuk mengganti perilaku ini untuk aplikasi yang perlu menjeda, bukan pengecilan 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 lain dari jenis aliran data masih berfungsi (misalnya, argumen streamType ke konstruktor AudioTrack yang tidak digunakan lagi), tetapi sistem mencatat hal ini sebagai error.
  • Saat menggunakan AudioTrack, jika aplikasi meminta buffer audio yang cukup besar, framework akan mencoba menggunakan output buffer dalam jika tersedia.
  • Di Android 8.0 (level API 26), penanganan peristiwa tombol media berbeda:
    1. Penanganan tombol media dalam aktivitas UI tidak berubah: aktivitas latar depan masih mendapatkan prioritas dalam menangani peristiwa tombol media.
    2. Jika aktivitas latar depan tidak menangani peristiwa tombol media, sistem akan mengarahkan 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.
    3. Jika sesi media aplikasi telah dirilis, sistem akan mengirim peristiwa tombol media ke MediaButtonReceiver aplikasi jika ada.
    4. Untuk setiap kasus lainnya, sistem menghapus kejadian tombol media.

Library native

Dalam aplikasi yang menargetkan Android 8.0 (API level 26), library native tidak akan dimuat lagi jika berisi segmen pemuatan apa pun yang dapat ditulis dan dieksekusi. Beberapa aplikasi dapat berhenti berfungsi karena perubahan ini jika memiliki library native dengan segmen pemuatan yang salah. Hal ini adalah tindakan hardening keamanan.

Untuk informasi selengkapnya, lihat Segmen yang Dapat Ditulis dan Dieksekusi.

Perubahan linker dikaitkan ke API level yang ditargetkan aplikasi. Jika ada perubahan penaut pada API level yang ditargetkan, aplikasi tidak dapat memuat library. Jika Anda menargetkan API level 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() diimplementasikan di atas List.sort(). Hal sebaliknya berlaku di Android 7.x (API level 24 dan 25): Implementasi default List.sort() yang disebut Collections.sort().

Perubahan ini memungkinkan Collections.sort() memanfaatkan implementasi List.sort() yang dioptimalkan, tetapi memiliki batasan berikut:

  • Implementasi List.sort() tidak boleh memanggil Collections.sort(), karena akan mengakibatkan stack overflow karena rekursi tanpa batas. Sebagai gantinya, jika Anda menginginkan perilaku default dalam implementasi List, jangan mengganti sort().

    Jika class induk mengimplementasikan sort() dengan tidak benar, biasanya tidak masalah untuk mengganti List.sort() dengan implementasi yang dibuat di atas List.toArray(), Arrays.sort(), dan ListIterator.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 sebagian besar kasus, Anda juga dapat mengganti List.sort() dengan implementasi yang didelegasikan ke berbagai implementasi default, 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 kedua hanya karena ingin agar metode sort() tersedia di semua level API, sebaiknya beri nama unik pada metode tersebut, seperti sortCompat(), bukan mengganti sort().

  • Collections.sort() kini dianggap sebagai modifikasi struktural dalam implementasi List yang memanggil sort(). Misalnya, pada versi platform sebelum Android 8.0 (API level 26), melakukan iterasi melalui ArrayList dan memanggil sort() di tengah iterasi akan menampilkan ConcurrentModificationException jika pengurutan dilakukan dengan memanggil List.sort(). Collections.sort() tidak menampilkan pengecualian.

    Perubahan ini membuat perilaku platform lebih konsisten: Salah satu pendekatan ini sekarang 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 apakah class tersebut direferensikan dari Java (dari forName()), Bytecode Dalvik, atau JNI. Platform tidak mencegat panggilan langsung dari Java ke metode loadClass(), serta tidak memeriksa hasil panggilan tersebut. Perilaku ini tidak boleh memengaruhi fungsi loader class yang berperilaku baik.

Platform akan memeriksa apakah deskripsi class yang ditampilkan loader class cocok dengan deskripsi yang diharapkan. Jika deskripsi yang ditampilkan tidak cocok, platform akan menampilkan error NoClassDefFoundError, dan dalam pengecualian, pesan mendetail yang menunjukkan perbedaan tersebut akan disimpan.

Platform juga akan memeriksa apakah deskriptor kelas yang diminta memang valid. Pemeriksaan ini menangkap panggilan JNI yang secara tidak langsung memuat class seperti GetFieldID(), yang 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 valid yang sepenuhnya memenuhi syarat.

Android 8.0 (API level 26) tidak mendukung memiliki beberapa loader class, cobalah untuk menentukan class menggunakan objek DexFile yang sama. Jika dilakukan, runtime Android akan menampilkan error InternalError dengan pesan "Try to register dex file <filename> with multiple class loaders".

DexFile API kini tidak digunakan lagi, dan Anda sangat dianjurkan untuk menggunakan salah satu classloader platform, termasuk PathClassLoader atau BaseDexClassLoader.

Catatan: Anda dapat membuat beberapa loader class yang mereferensikan penampung file APK atau JAR yang sama dari sistem file. Cara tersebut biasanya tidak menghasilkan banyak overhead memori: Jika file DEX dalam container 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 untuk memuat class yang sama dengan loader class yang sama, thread pertama yang menyelesaikan operasi akan menang, dan hasilnya digunakan untuk 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: Pada versi platform yang lebih rendah dari Android 8.0 (API level 26), merusak asumsi ini dapat menyebabkan penentuan class yang sama beberapa kali, kerusakan heap karena kebingungan class, dan efek yang tidak diinginkan lainnya.