Menangani perubahan konfigurasi

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Sebagian konfigurasi perangkat bisa berubah saat runtime (misalnya orientasi layar, ketersediaan keyboard, dan saat pengguna mengaktifkan mode multi-aplikasi). Saat perubahan tersebut terjadi, Android akan memulai ulang Activity yang berjalan (onDestroy() dipanggil, diikuti dengan onCreate()). Perilaku mulai ulang didesain untuk membantu aplikasi Anda beradaptasi dengan konfigurasi baru melalui pemuatan ulang aplikasi secara otomatis dengan resource alternatif yang sesuai dengan konfigurasi perangkat baru.

Untuk menangani secara tepat mulai ulang, penting bahwa aktivitas Anda memulihkan status sebelumnya. Anda bisa menggunakan kombinasi objek onSaveInstanceState(), ViewModel, dan penyimpanan persisten untuk menyimpan dan memulihkan status UI aktivitas Anda di seluruh perubahan UI. Untuk informasi selengkapnya tentang cara menyimpan status Aktivitas Anda, baca Menyimpan status UI.

Untuk menguji bahwa aplikasi memulai ulang sendiri dengan status tak berubah, Anda harus memanggil perubahan konfigurasi (seperti mengubah orientasi layar) saat melakukan berbagai tugas dalam aplikasi. Aplikasi Anda harus dapat memulai ulang setiap saat tanpa kehilangan data pengguna atau status untuk menangani peristiwa seperti perubahan konfigurasi atau bila pengguna menerima panggilan telepon masuk lalu kembali ke aplikasi setelah proses aplikasi Anda dimusnahkan. Untuk mengetahui cara mengembalikan status aktivitas, bacalah tentang Siklus proses aktivitas.

Akan tetapi, Anda mungkin menemui situasi ketika memulai ulang aplikasi dan memulihkan data dalam jumlah besar bisa menjadi mahal dan menghasilkan pengalaman pengguna yang buruk. Dalam situasi demikian, Anda memiliki dua opsi lain:

  1. Mempertahankan objek selama perubahan konfigurasi

    Izinkan aktivitas Anda memulai ulang saat konfigurasi berubah, namun bawa objek berstatus ke instance baru aktivitas Anda.

  2. Menangani sendiri perubahan konfigurasi

    Tidak disarankan menangani sendiri perubahan konfigurasi karena kompleksitas tersembunyi dalam menangani perubahan konfigurasi. Namun, jika tidak dapat mempertahankan status UI menggunakan opsi yang lebih disukai (objek onSaveInstanceState(), ViewModel, dan penyimpanan persistent) Anda dapat mencegah sistem memulai ulang aktivitas selama perubahan konfigurasi tertentu. Aplikasi Anda akan menerima callback ketika konfigurasi melakukan perubahan, sehingga jika diperlukan, Anda dapat memperbarui aktivitas secara manual.

Mempertahankan objek selama perubahan konfigurasi

Jika memulai ulang aktivitas mengharuskan pemulihan serangkaian data dalam jumlah besar, menghubungkan kembali koneksi jaringan, atau melakukan operasi intensif lainnya, maka mulai ulang penuh karena perubahan konfigurasi mungkin menjadi pengalaman pengguna yang lambat. Selain itu, Anda mungkin tidak bisa sepenuhnya memulihkan status aktivitas dengan Bundle yang disimpan sistem untuk Anda dengan callback onSaveInstanceState() —Bundle tidak didesain untuk membawa objek besar (seperti bitmap) dan data di dalamnya harus diserialkan kemudian dinonserialkan di thread utama, yang bisa menghabiskan banyak memori dan membuat perubahan konfigurasi menjadi lambat. Dalam situasi demikian, Anda dapat mengurangi beban menginisialisasi ulang bagian dari aktivitas Anda menggunakan ViewModel. Objek ViewModel dipertahankan saat perubahan konfigurasi, sehingga ini merupakan tempat yang bagus untuk menyimpan data UI tanpa harus mengirim kueri lagi. Untuk informasi selengkapnya tentang penggunaan class ViewModel di aplikasi Anda, baca ringkasan ViewModel.

Menangani sendiri perubahan konfigurasi

Jika aplikasi Anda tidak memerlukan pembaruan resource selama perubahan konfigurasi tertentu dan Anda memiliki keterbatasan kinerja yang mengharuskan Anda untuk menghindari mulai ulang aktivitas, maka Anda bisa mendeklarasikan agar aktivitas Anda menangani sendiri perubahan konfigurasinya, sehingga mencegah sistem memulai ulang aktivitas.

Peringatan: Menangani sendiri perubahan konfigurasi bisa jauh lebih mempersulit penggunaan resource alternatif, karena sistem tidak menerapkannya secara otomatis untuk Anda. Teknik ini harus dianggap sebagai usaha terakhir bila Anda harus menghindari mulai ulang karena perubahan konfigurasi dan tidak disarankan untuk sebagian besar aplikasi.

Untuk mendeklarasikan agar aktivitas Anda menangani perubahan konfigurasi, edit elemen <activity> yang sesuai dalam file manifes agar menyertakan atribut android:configChanges dengan nilai yang mewakili konfigurasi yang ingin ditangani. Nilai yang memungkinkan dicantumkan dalam dokumentasi untuk atribut android:configChanges . Nilai yang paling umum digunakan adalah "orientation", "screenSize", "screenLayout", dan "keyboardHidden":

  • Nilai "orientation" mencegah mulai ulang saat orientasi layar berubah.
  • Nilai "screenSize" juga mencegah mulai ulang saat orientasi berubah, tetapi hanya untuk Android 3.2 (API level 13) dan yang lebih tinggi.
  • Nilai "screenLayout" diperlukan untuk mendeteksi perubahan yang dapat dipicu oleh perangkat seperti ponsel foldable dan Chromebook konvertibel.
  • Nilai "keyboardHidden" mencegah mulai ulang saat ketersediaan keyboard berubah.

Jika ingin menangani perubahan konfigurasi secara manual di aplikasi, Anda harus mendeklarasikan nilai "orientation", "screenSize" dan "screenLayout" di atribut android:configChanges. Anda bisa mendeklarasikan beberapa nilai konfigurasi dalam atribut dengan memisahkannya menggunakan karakter pipa |.

Misalnya, kode manifes berikut menyatakan aktivitas yang menangani perubahan orientasi layar maupun perubahan ketersediaan keyboard:

<activity android:name=".MyActivity"
          android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
          android:label="@string/app_name">

Sekarang, saat perubahan terjadi di salah satu konfigurasi ini, MyActivity tidak akan dimulai ulang. Sebagai gantinya, MyActivity menerima panggilan ke onConfigurationChanged().

Metode onConfigurationChanged() meneruskan objek Configuration yang menetapkan konfigurasi perangkat baru. Dengan membaca kolom dalam objek Configuration, Anda dapat menentukan konfigurasi baru dan membuat perubahan yang sesuai dengan memperbarui resource yang digunakan dalam antarmuka. Pada saat metode ini dipanggil, objek Resources aktivitas Anda akan diperbarui untuk menampilkan resource berdasarkan konfigurasi baru, jadi Anda bisa dengan mudah menyetel ulang elemen UI tanpa membuat sistem memulai ulang aktivitas Anda.

Misalnya, implementasi onConfigurationChanged() berikut akan memeriksa orientasi perangkat saat ini:

Kotlin

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)

    // Checks the orientation of the screen
    if (newConfig.orientation === Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show()
    } else if (newConfig.orientation === Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show()
    }
}

Java

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}

Objek Configuration mewakili semua konfigurasi saat ini, tidak hanya konfigurasi yang telah berubah. Sering kali Anda tidak perlu memperhatikan dengan persis bagaimana konfigurasi berubah dan cukup menetapkan kembali semua resource yang memberikan alternatif untuk konfigurasi yang sedang ditangani. Misalnya, karena objek Resources sekarang diperbarui, Anda dapat menyetel ulang instance ImageView dengan setImageResource() dan resource yang sesuai untuk konfigurasi baru digunakan (seperti yang dijelaskan dalam Ringkasan resource aplikasi).

Perhatikan bahwa nilai-nilai dari kolom Configuration adalah bilangan bulat yang sesuai dengan konstanta spesifik dari class Configuration. Untuk dokumentasi tentang konstanta yang harus digunakan di setiap kolom, lihat kolom yang sesuai dalam referensi Configuration.

Ingat: Saat mendeklarasikan aktivitas untuk menangani perubahan konfigurasi, Anda bertanggung jawab untuk menyetel ulang setiap elemen yang alternatifnya Anda berikan. Jika Anda mendeklarasikan aktivitas untuk menangani perubahan orientasi dan memiliki gambar yang harus berubah antara lanskap dan potret, Anda harus menetapkan kembali setiap resource ke tiap elemen selama onConfigurationChanged().

Jika Anda tidak perlu memperbarui aplikasi berdasarkan perubahan konfigurasi ini, sebagai gantinya 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.

Namun, jangan menganggap teknik ini sebagai pengalihan dari mempertahankan status selama siklus proses aktivitas normal. Aplikasi Anda harus selalu dapat dimatikan dan dimulai ulang dengan status sebelumnya tetap utuh. Perubahan konfigurasi yang tidak dapat Anda cegah dapat memulai ulang aplikasi. Jika pengguna keluar dari aplikasi dan aplikasi ditempatkan di latar belakang, sistem mungkin akan mengakhiri proses aplikasi tersebut.