PAI - Portal Android Indonesia - Menangani Perubahan Waktu Proses - Sebagian konfigurasi perangkat bisa berubah selama waktu proses (seperti orientasi layar, ketersediaan keyboard, dan bahasa). Saat perubahan demikian terjadi, Android akan memulai ulang Activity
yang berjalan (onDestroy()
dipanggil, diikuti oleh onCreate()
). Perilaku mulai ulang didesain untuk membantu aplikasi Anda beradaptasi dengan konfigurasi baru melalui pemuatan ulang aplikasi Anda secara otomatis dengan
sumber daya alternatif sumber yang sesuai dengan konfigurasi perangkat baru.
Untuk menangani mulai ulang dengan benar, aktivitas Anda harus mengembalikan statusnya seperti semula melalui Daur hidup aktivitas normal, dalam hal ini Android akan memanggil onSaveInstanceState()
sebelum menghentikan
aktivitas Anda sehingga Anda dapat menyimpan data mengenai status aplikasi. Selanjutnya Anda bisa memulihkan statusnya
selama onCreate()
atau onRestoreInstanceState()
.
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 kejadian 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 Daur hidup aktivitas.
Akan tetapi, Anda mungkin menemui situasi ketika memulai ulang aplikasi dan mengembalikan data dalam jumlah besar malah menjadi mahal dan menghasilkan pengalaman pengguna yang buruk. Dalam situasi demikian, Anda memiliki dua opsi lain :
- Mempertahankan objek selama perubahan konfigurasi
Izinkan aktivitas Anda memulai ulang saat konfigurasi berubah, namun bawa objek berstatus ke instance baru aktivitas Anda. - Menangani sendiri perubahan konfigurasi
Cegah sistem memulai ulang aktivitas selama perubahan konfigurasi tertentu, namun terima callback saat konfigurasi benar-benar berubah, agar Anda bisa memperbarui aktivitas secara manual bila diperlukan.
Mempertahankan Objek Selama Perubahan Konfigurasi
Jika memulai ulang aktivitas mengharuskan pemulihan seperangkat 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 denganBundle
yang disimpan sistem untuk Anda dengan callback onSaveInstanceState()
Itu tidaklah didesain untuk membawa objek besar (seperti bitmap) dan data di dalamnya harus diserialkan kemudian dinonserialkan, yang bisa menghabiskan banyak memori dan membuat perubahan konfigurasi menjadi lambat. Dalam situasi demikian, Anda bisa meringankan beban memulai kembali aktivitas Anda dengan mempertahankan
Fragment
bila aktivitas Anda dimulai ulang karena perubahan konfigurasi. Fragmen ini bisa berisi acuan ke objek stateful yang ingin Anda pertahankan.Bila sistem Android menghentikan aktivitas Anda karena perubahan konfigurasi, fragmen aktivitas yang telah ditandai untuk ipertahankan tidak akan dimusnahkan. Anda dapat menambahkan fragmen tersebut ke aktivitas untuk mempertahankan objek stateful.
Untuk mempertahankan objek stateful dalam fragmen selama perubahan konfigurasi waktu proses :
- Perluas kelas
Fragment
dan deklarasikan referensi ke objek stateful Anda. - Panggil
setRetainInstance(boolean)
saat fragmen dibuat. - Tambahkan fragmen ke aktivitas.
- Gunakan
FragmentManager
untuk mengambil fragmen bila aktivitas dimulai ulang.
Misalnya, definisikan fragmen sebagai berikut :
public class RetainedFragment extends Fragment {
// data object we want to retain
private MyDataObject data;
// this method is only called once for this fragment
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// retain this fragment
setRetainInstance(true);
}
public void setData(MyDataObject data) {
this.data = data;
}
public MyDataObject getData() {
return data;
}
}
Perhatian : Meskipun bisa menyimpan objek apa saja, Anda sama sekali tidak boleh meneruskan objek yang terkait denganKemudian gunakanActivity
, sepertiDrawable
,Adapter
,View
atau objek lainnya yang terkait denganContext
. Jika Anda melakukannya, hal tersebut akan membocorkan semua tampilan dan sumber daya instance aktivitas semula. (Sumber daya yang bocor berarti bahwa aplikasi Anda tetap menyimpannya dan tidak bisa dijadikan kumpulan sampah, sehingga bisa banyak memori yang hilang.)
FragmentManager
untuk menambahkan fragmen ke aktivitas.
Anda bisa memperoleh objek data dari fragmen saat aktivitas memulai kembali selama perubahan
konfigurasi waktu proses. Misalnya, definisikan aktivitas Anda sebagai berikut :public class MyActivity extends Activity {
private RetainedFragment dataFragment;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// find the retained fragment on activity restarts
FragmentManager fm = getFragmentManager();
dataFragment = (DataFragment) fm.findFragmentByTag(“data”);
// create the fragment and data the first time
if (dataFragment == null) {
// add the fragment
dataFragment = new DataFragment();
fm.beginTransaction().add(dataFragment, “data”).commit();
// load the data from the web
dataFragment.setData(loadMyData());
}
// the data is available in dataFragment.getData()
...
}
@Override
public void onDestroy() {
super.onDestroy();
// store the data in the fragment
dataFragment.setData(collectMyLoadedData());
}
}
Dalam contoh ini, onCreate()
menambahkan fragmen atau memulihkan referensi ke fragmen. onCreate()
juga menyimpan objek stateful dalam instance fragmen.
onDestroy()
akan memperbarui objek stateful dalam instance fragmen yang dipertahankan.
Menangani Sendiri Perubahan Konfigurasi
Jika aplikasi Anda tidak memerlukan pembaruan sumber daya 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.Catatan: Menangani sendiri perubahan konfigurasi bisa jauh lebih mempersulit penggunaan sumber daya 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 tercantum dalam dokumentasi untuk atribut android:configChanges
(nilai yang paling sering digunakan adalah "orientation"
untuk mencegah mulai ulang bila orientasi layar berubah dan "keyboardHidden"
untuk mencegah mulai ulang bila ketersediaan keyboard berubah). 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|keyboardHidden"
android:label="@string/app_name">
Sekarang, bila salah satu konfigurasi ini berubah, MyActivity
tidak akan dimulai ulang. Sebagai gantinya, MyActivity
akan menerima panggilan ke onConfigurationChanged()
. Metode ini meneruskan objek Configuration
yang menetapkan konfigurasi perangkat baru. Dengan membaca bidang-bidang dalam Configuration
, Anda dapat menentukan konfigurasi baru dan membuat perubahan yang sesuai dengan memperbarui sumber daya yang digunakan dalam antarmuka. Pada saat metode ini dipanggil, objek Resources
aktivitas Anda akan diperbarui untuk mengembalikan sumber daya berdasarkan konfigurasi baru, jadi Anda bisa dengan mudah menyetel ulang elemen UI tanpa membuat sistem memulai ulang aktivitas Anda.
Perhatian: Mulai Android 3.2 (API level 13), "ukuran layar" juga berubah bila perangkat beralih orientasi antara potret dan lanskap. Jadi jika Anda tidak ingin waktu proses dimulai ulang karena perubahan orientasi saat mengembangkan untuk API level 13 atau yang lebih tinggi (sebagaimana dideklarasikan oleh atributMisalnya, implementasiminSdkVersion
dantargetSdkVersion
), Anda harus menyertakan nilai"screenSize"
selain nilai"orientation"
. Yaitu, Anda harus mendeklarasikanandroid:configChanges="orientation|screenSize"
. Akan tetapi, jika aplikasi Anda menargetkan API level 12 atau yang lebih rendah, maka aktivitas Anda akan selalu menangani sendiri perubahan konfigurasi ini (perubahan konfigurasi ini tidak memulai ulang aktivitas Anda, bahkan saat berjalan pada perangkat Android 3.2 atau yang lebih tinggi)
onConfigurationChanged()
berikut akan memeriksa orientasi perangkat saat ini :@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 sumber daya yang memberikan alternatif untuk konfigurasi sedang ditangani. Misalnya, karena objek Resources
sekarang telah diperbarui, Anda bisa menyetel ulang
semua ImageView
dengan setImageResource()
dan sumber daya yang sesuai untuk konfigurasi baru yang digunakan (seperti yang dijelaskan dalam Menyediakan Sumber Daya).Perhatikan bahwa nilai-nilai dari bidang
Configuration
adalah integer yang sesuai dengan konstanta spesifik
dari kelas Configuration
. Untuk dokumentasi tentang konstanta yang harus digunakan di setiap bidang, lihat bidang yang sesuai dalam referensi Configuration
.
Ingatlah: 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 sumber daya 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 sumber daya yang digunakan sebelum perubahan konfigurasi akan tetap digunakan dan Anda hanya menghindari mulai ulang aktivitas.Akan tetapi, aplikasi Anda harus selalu bisa dimatikan dan dimulai ulang dengan status sebelumnya tetap utuh, sehingga Anda jangan menganggap teknik ini sebagai jalan keluar untuk mempertahankan status selama daur hidup aktivitas normal. Tidak hanya karena ada perubahan konfigurasi lainnya yang tidak bisa Anda cegah untuk memulai ulang aplikasi, namun juga karena Anda harus menangani kejadian seperti saat pengguna meninggalkan aplikasi dan dimusnahkan sebelum pengguna kembali ke plikasi.
Untuk informasi selengkapnya tentang perubahan konfigurasi yang bisa Anda tangani dalam aktivitas, lihat dokumentasi code>android:configChanges dan kelas
Configuration
.