Beberapa konfigurasi perangkat dapat berubah saat aplikasi berjalan. Perubahan tersebut mencakup, namun tidak terbatas pada:
- Ukuran tampilan aplikasi
- Orientasi layar
- Ketebalan dan ukuran font
- Lokalitas
- Mode gelap versus mode terang
- Ketersediaan keyboard
Sebagian besar perubahan konfigurasi ini terjadi karena beberapa interaksi pengguna. Misalnya,
memutar atau melipat perangkat akan mengubah jumlah ruang layar
yang tersedia untuk aplikasi Anda. Demikian pula, mengubah setelan perangkat seperti ukuran font,
bahasa, atau tema pilihan akan mengubah nilainya dalam objek
Configuration
.
Parameter ini biasanya memerlukan perubahan yang cukup besar pada UI aplikasi Anda
agar platform Android memiliki mekanisme yang dibuat khusus saat berubah.
Mekanisme ini adalah pembuatan ulang Activity
.
Pembuatan ulang aktivitas
Sistem membuat ulang Activity
saat terjadi perubahan konfigurasi. Untuk melakukannya, sistem
memanggil onDestroy()
dan menghancurkan instance Activity
yang ada. Kemudian, sistem
akan membuat instance baru menggunakan onCreate()
, dan instance Activity
baru ini
diinisialisasi dengan konfigurasi baru yang diupdate. Ini juga berarti bahwa sistem
juga membuat ulang UI dengan konfigurasi baru.
Perilaku pembuatan ulang membantu aplikasi Anda beradaptasi dengan konfigurasi baru melalui pemuatan ulang aplikasi secara otomatis menggunakan resource alternatif yang sesuai dengan konfigurasi perangkat baru.
Contoh pembuatan ulang
Pertimbangkan TextView
yang menampilkan judul statis menggunakan
android:text="@string/title"
, seperti yang ditentukan dalam file XML tata letak. Saat
dibuat, tampilan akan menyetel teks sekali saja, berdasarkan bahasa saat ini. Jika
bahasa berubah, sistem akan membuat ulang aktivitas. Akibatnya, sistem
juga akan membuat ulang tampilan dan melakukan inisialisasi ke nilai yang benar berdasarkan bahasa
baru.
Pembuatan ulang juga menghapus semua status yang disimpan sebagai kolom dalam
Activity
atau di Fragment
, View
, atau objek lain yang ada di dalamnya. Hal ini
karena pembuatan ulang Activity
membuat instance Activity
dan UI yang benar-benar baru. Selain itu, Activity
lama tidak lagi terlihat atau valid, sehingga
referensi lainnya ke aktivitas tersebut atau objek di dalamnya sudah usang. Hal itu dapat menyebabkan
bug, kebocoran memori, dan error.
Ekspektasi pengguna
Pengguna aplikasi mengharapkan status dipertahankan. Jika pengguna sedang mengisi formulir dan membuka aplikasi lain dalam mode multi-aplikasi untuk merujuk informasi, aplikasi adalah pengalaman pengguna yang buruk jika mereka kembali ke formulir yang telah diperbaiki atau di tempat lain di aplikasi secara keseluruhan. Sebagai developer, Anda harus memberikan pengalaman pengguna yang konsisten melalui perubahan konfigurasi dan pembuatan ulang aktivitas.
Untuk memastikan apakah status dipertahankan di aplikasi, Anda dapat melakukan tindakan yang menyebabkan perubahan konfigurasi saat aplikasi berada di latar depan maupun di latar belakang. Tindakan ini termasuk:
- Memutar perangkat
- Memasuki mode multi-aplikasi
- Mengubah ukuran aplikasi saat dalam mode multi-aplikasi atau jendela bentuk bebas
- Melipat perangkat foldable dengan beberapa layar
- Mengubah tema sistem, seperti mode gelap versus mode terang
- Mengubah ukuran font
- Mengubah bahasa sistem atau aplikasi
- Menyambungkan atau memutuskan sambungan keyboard hardware
- Menyambungkan atau memutuskan sambungan dok
Ada tiga pendekatan utama yang dapat Anda lakukan untuk mempertahankan status yang relevan melalui
pembuatan ulang Activity
. Yang akan digunakan bergantung pada jenis status yang ingin Anda pertahankan:
- Persistensi lokal guna menangani penghentian proses untuk data yang kompleks atau besar.
Penyimpanan lokal persisten mencakup database atau
DataStore
. - Objek yang dipertahankan seperti instance
ViewModel
untuk menangani status terkait UI di memori saat pengguna aktif menggunakan aplikasi. - Status instance tersimpan untuk menangani penghentian proses yang dimulai oleh sistem dan mempertahankan status sementara yang bergantung pada input atau navigasi pengguna.
Untuk membaca secara mendetail tentang API untuk setiap status dan saat yang tepat untuk menggunakan masing-masing, lihat Menyimpan status UI.
Membatasi pembuatan ulang aktivitas
Anda dapat mencegah pembuatan ulang aktivitas otomatis untuk perubahan konfigurasi tertentu.
Pembuatan ulang Activity
menghasilkan pembuatan ulang seluruh UI, dan objek apa pun yang berasal
dari Activity
. Anda mungkin memiliki alasan yang baik untuk menghindari hal ini. Misalnya,
aplikasi Anda mungkin tidak perlu memperbarui resource selama perubahan
konfigurasi tertentu, atau Anda mungkin memiliki batasan performa. Dalam hal ini, Anda dapat mendeklarasikan bahwa aktivitas Anda menangani perubahan konfigurasinya sendiri dan
mencegah sistem memulai ulang aktivitas.
Untuk menonaktifkan pembuatan ulang aktivitas bagi perubahan konfigurasi tertentu,
tambahkan jenis konfigurasi ke android:configChanges
dalam
entri <activity>
dalam file AndroidManifest.xml
Anda. Nilai yang mungkin muncul dalam
dokumentasi untuk atribut android:configChanges
.
Kode manifes berikut menonaktifkan pembuatan ulang Activity
untuk MyActivity
saat
orientasi layar dan ketersediaan keyboard berubah:
<activity
android:name=".MyActivity"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:label="@string/app_name">
Beberapa perubahan konfigurasi selalu menyebabkan aktivitas dimulai ulang. Anda tidak dapat menonaktifkannya. Misalnya, Anda tidak dapat menonaktifkan perubahan warna dinamis yang diperkenalkan di Android 12L (API level 32).
Merespons perubahan konfigurasi dalam sistem Tampilan
Dalam sistem View
, saat terjadi perubahan konfigurasi yang telah Anda
nonaktifkan pembuatan ulang Activity
-nya, aktivitas akan menerima panggilan ke
Activity.onConfigurationChanged()
. Setiap tampilan yang dilampirkan juga akan menerima
panggilan ke View.onConfigurationChanged()
. Untuk perubahan konfigurasi yang
belum Anda tambahkan ke android:configChanges
, sistem akan membuat ulang aktivitas
seperti biasa.
Metode callback onConfigurationChanged()
menerima
objek Configuration
yang menentukan konfigurasi perangkat baru. Baca
kolom dalam objek Configuration
untuk menentukan konfigurasi
baru Anda. Untuk membuat perubahan berikutnya, perbarui resource
yang Anda gunakan di antarmuka. Saat sistem memanggil metode ini, objek
Resources
aktivitas Anda akan diupdate untuk menampilkan resource berdasarkan konfigurasi
baru. Hal ini memungkinkan Anda mereset elemen UI tanpa membuat sistem
memulai ulang aktivitas Anda.
Misalnya, implementasi onConfigurationChanged()
berikut memeriksa
apakah keyboard tersedia:
Kotlin
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
// Checks whether a keyboard is available
if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_YES) {
Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show()
} else if (newConfig.keyboardHidden === Configuration.KEYBOARDHIDDEN_NO) {
Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show()
}
}
Java
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Checks whether a keyboard is available
if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_YES) {
Toast.makeText(this, "Keyboard available", Toast.LENGTH_SHORT).show();
} else if (newConfig.keyboardHidden == Configuration.KEYBOARDHIDDEN_NO){
Toast.makeText(this, "No keyboard", Toast.LENGTH_SHORT).show();
}
}
Jika Anda tidak perlu mengupdate aplikasi berdasarkan perubahan
konfigurasi ini, Anda bisa saja tidak mengimplementasikan onConfigurationChanged()
. Dalam
hal ini, semua resource yang digunakan sebelum perubahan konfigurasi akan tetap digunakan,
dan Anda hanya menghindari mulai ulang aktivitas. Misalnya, aplikasi TV
mungkin tidak ingin bereaksi saat keyboard Bluetooth terpasang atau dilepas.
Mempertahankan status
Saat menggunakan teknik ini, Anda tetap harus mempertahankan status selama siklus proses aktivitas normal. Hal ini terjadi karena hal berikut:
- Perubahan yang tidak dapat dihindari: perubahan konfigurasi yang tidak dapat dicegah dapat memulai ulang aplikasi.
- Penghentian proses: aplikasi Anda harus mampu menangani penghentian proses yang dimulai oleh sistem. Jika pengguna keluar dari aplikasi dan aplikasi beralih ke latar belakang, sistem mungkin akan mengakhiri proses aplikasi tersebut.
Merespons perubahan konfigurasi di Jetpack Compose
Jetpack Compose memungkinkan aplikasi Anda bereaksi lebih mudah terhadap perubahan konfigurasi.
Namun, jika Anda menonaktifkan pembuatan ulang Activity
untuk semua perubahan konfigurasi yang
memungkinkan, aplikasi Anda masih harus menangani
perubahan konfigurasi dengan benar.
Objek Configuration
tersedia dalam hierarki UI Compose dengan
lokal komposisi LocalConfiguration
. Setiap kali berubah,
fungsi composable dapat membaca dari rekomposisi LocalConfiguration.current
. Untuk
mengetahui informasi tentang cara kerja lokal komposisi, lihat Data yang
dibatasi secara lokal dengan CompositionLocal.
Contoh
Pada contoh berikut, composable menampilkan tanggal dengan format tertentu.
Composable bereaksi terhadap perubahan konfigurasi lokalitas sistem dengan memanggil
ConfigurationCompat.getLocales()
dengan LocalConfiguration.current
.
@Composable
fun DateText(year: Int, dayOfYear: Int) {
val dateTimeFormatter = DateTimeFormatter.ofPattern(
"MMM dd",
ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
)
Text(
dateTimeFormatter.format(LocalDate.ofYearDay(year, dayOfYear))
)
}
Untuk menghindari pembuatan ulang Activity
saat lokalitas berubah, Activity
yang menghosting
kode Compose harus memilih untuk tidak mengikuti perubahan konfigurasi lokalitas. Untuk melakukannya, tetapkan
android:configChanges
ke locale|layoutDirection
.
Perubahan konfigurasi: Konsep utama dan praktik terbaik
Berikut adalah konsep utama yang perlu Anda ketahui saat menangani perubahan konfigurasi:
- Konfigurasi: konfigurasi perangkat menentukan cara UI ditampilkan kepada pengguna, seperti ukuran tampilan aplikasi, lokalitas, atau tema sistem.
- Perubahan konfigurasi: konfigurasi berubah melalui interaksi pengguna. Misalnya, pengguna mungkin mengubah setelan perangkat atau cara mereka berinteraksi secara fisik dengan perangkat. Tidak ada cara untuk mencegah perubahan konfigurasi.
- Pembuatan ulang
Activity
: Perubahan konfigurasi menghasilkan pembuatan ulangActivity
secara default. Ini adalah mekanisme bawaan untuk menginisialisasi ulang status aplikasi untuk konfigurasi baru. - Penghancuran
Activity
: Pembuatan ulangActivity
menyebabkan sistem menghancurkan instanceActivity
lama dan membuat instance baru sebagai gantinya. Instance lama sudah tidak digunakan lagi. Referensi apa pun yang tersisa akan mengakibatkan kebocoran memori, bug, atau error. - Status: status dalam instance
Activity
lama tidak ada dalam instanceActivity
baru, karena keduanya adalah dua instance objek yang berbeda. Pertahankan aplikasi dan status pengguna seperti yang dijelaskan dalam Menyimpan status UI. - Penonaktifan: penonaktifan pembuatan ulang aktivitas untuk jenis perubahan konfigurasi adalah kemungkinan pengoptimalan. Aplikasi Anda harus diupdate dengan benar sebagai reaksi terhadap konfigurasi baru.
Untuk memberikan pengalaman pengguna yang baik, ikuti praktik terbaik berikut:
- Bersiaplah untuk perubahan konfigurasi yang sering terjadi: jangan berasumsi bahwa perubahan konfigurasi jarang atau tidak pernah terjadi, terlepas dari API level, faktor bentuk, atau toolkit UI. Saat menyebabkan perubahan konfigurasi, pengguna ingin aplikasi melakukan update dan terus berfungsi dengan benar dengan konfigurasi baru.
- Pertahankan status: jangan sampai status pengguna hilang saat pembuatan ulang
Activity
terjadi. Pertahankan status seperti yang dijelaskan dalam Menyimpan status UI. - Hindari penonaktifan sebagai perbaikan cepat: jangan menonaktifkan pembuatan ulang
Activity
sebagai pintasan untuk menghindari hilangnya status. Penonaktifan pembuatan ulang aktivitas mengharuskan Anda memenuhi janji untuk menangani perubahan, dan Anda masih dapat kehilangan status karena pembuatan ulangActivity
dari perubahan konfigurasi lainnya, penghentian proses, atau penutupan aplikasi. Anda tidak dapat sepenuhnya menonaktifkan pembuatan ulangActivity
. Pertahankan status seperti yang dijelaskan dalam Menyimpan status UI. - Jangan hindari perubahan konfigurasi: jangan terapkan batasan pada orientasi,
rasio aspek, atau kemampuan mengubah ukuran untuk menghindari perubahan konfigurasi dan
pembuatan ulang
Activity
. Hal ini berdampak negatif terhadap pengguna yang ingin menggunakan aplikasi Anda dengan cara yang mereka inginkan.
Menangani perubahan konfigurasi berbasis ukuran
Perubahan konfigurasi berbasis ukuran dapat terjadi kapan saja dan lebih mungkin terjadi saat aplikasi berjalan di perangkat layar besar tempat pengguna dapat memasuki mode multi-aplikasi. Mereka menginginkan aplikasi Anda berfungsi dengan baik di lingkungan tersebut.
Ada dua jenis umum perubahan ukuran: signifikan dan tidak signifikan. Perubahan ukuran yang signifikan adalah perubahan sumber daya alternatif berlaku pada konfigurasi baru karena perbedaan ukuran layar, seperti lebar, tinggi, atau lebar terkecil. Resource ini mencakup resource yang ditentukan aplikasi itu sendiri dan resource dari library mana pun.
Membatasi pembuatan ulang aktivitas untuk perubahan konfigurasi berbasis ukuran
Jika Anda menonaktifkan pembuatan ulang Activity
untuk perubahan konfigurasi berbasis ukuran,
sistem tidak akan membuat ulang Activity
. Sebagai gantinya, sistem akan menerima panggilan ke
Activity.onConfigurationChanged()
. Setiap tampilan yang dilampirkan akan menerima panggilan ke
View.onConfigurationChanged()
.
Pembuatan ulang Activity
dinonaktifkan untuk perubahan konfigurasi berbasis ukuran saat
Anda memiliki
android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout
"
di file manifes.
Mengizinkan pembuatan ulang aktivitas untuk perubahan konfigurasi berbasis ukuran
Di Android 7.0 (API level 24) dan yang lebih tinggi, pembuatan ulang Activity
hanya terjadi untuk perubahan konfigurasi
berbasis ukuran jika perubahan ukuran itu signifikan. Jika sistem tidak
membuat ulang Activity
karena ukurannya tidak memadai, sistem mungkin akan memanggil
Activity.onConfigurationChanged()
dan
View.onConfigurationChanged()
sebagai gantinya.
Ada beberapa peringatan yang harus diamati terkait callback Activity
dan View
saat Activity
tidak dibuat ulang:
- Di Android 11 (level API 30) hingga Android 13 (level API 33),
Activity.onConfigurationChanged()
tidak dipanggil. - Ada masalah umum saat
View.onConfigurationChanged()
mungkin tidak dipanggil dalam beberapa kasus di Android 12L (level API 32) dan versi awal Android 13 (level API 33). Untuk informasi selengkapnya, lihat masalah publik ini. Masalah ini telah diatasi dalam rilis Android 13 dan Android 14 yang lebih baru.
Untuk kode yang bergantung pada pemrosesan perubahan konfigurasi berbasis ukuran,
sebaiknya gunakan View
utilitas dengan View.onConfigurationChanged()
yang diganti, bukan mengandalkan pembuatan ulang Activity
atau
Activity.onConfigurationChanged()
.