Aktivitas

Activity adalah sebuah komponen aplikasi yang menyediakan layar yang digunakan pengguna untuk berinteraksi guna melakukan sesuatu, misalnya memilih nomor ponsel, mengambil foto, mengirim email, atau menampilkan peta. Tiap aktivitas diberi sebuah jendela untuk menggambar antarmuka penggunanya. Jendela ini biasanya mengisi layar, namun mungkin lebih kecil daripada layar dan mengambang di atas jendela lain.

Sebuah aplikasi biasanya terdiri atas beberapa aktivitas yang terikat secara longgar satu sama lain. Biasanya, satu aktivitas dalam aplikasi ditetapkan sebagai aktivitas "utama", yang ditampilkan kepada pengguna saat membuka aplikasi untuk pertama kali. Tiap aktivitas kemudian bisa memulai aktivitas lain untuk melakukan berbagai tindakan. Tiap kali aktivitas baru dimulai, aktivitas sebelumnya akan dihentikan, namun sistem mempertahankan aktivitas dalam sebuah tumpukan ("back-stack"). Bila sebuah aktivitas baru dimulai, aktivitas itu akan didorong ke atas back-stack dan mengambil fokus pengguna. Back-stack mematuhi mekanisme dasar tumpukan "masuk terakhir, keluar pertama", jadi, bila pengguna selesai dengan aktivitas saat ini dan menekan tombol Kembali, aktivitas akan dikeluarkan dari tumpukan (dan dimusnahkan) dan aktivitas sebelumnya akan dilanjutkan. (Back-stack dibahas selengkapnya dalam dokumen Tugas dan Back-Stack.)

Bila aktivitas dihentikan karena ada aktivitas baru yang dimulai, aktivitas lama akan diberi tahu tentang perubahan status ini melalui metode callback daur hidupnya. Ada beberapa metode callback yang mungkin diterima aktivitas, karena sebuah perubahan dalam statusnya—apakah sistem sedang membuatnya, menghentikannya, melanjutkannya, atau menghapuskannya—dan masing-masing callback memberi Anda kesempatan melakukan pekerjaan tertentu yang sesuai untuk perubahan status itu. Misalnya, bila dihentikan, aktivitas Anda harus melepas objek besar, seperti koneksi jaringan atau database. Bila aktivitas dilanjutkan, Anda bisa memperoleh kembali sumber daya yang diperlukan dan melanjutkan tindakan yang terputus. Transisi status ini semuanya bagian dari daur hidup aktivitas.

Bagian selebihnya dari dokumen ini membahas dasar-dasar cara membangun dan menggunakan aktivitas, yang meliputi satu pembahasan lengkap tentang cara kerja daur hidup aktivitas, sehingga Anda bisa dengan benar mengelola transisi di antara berbagai status aktivitas.

Membuat Aktivitas

Untuk membuat sebuah aktivitas, Anda harus membuat subkelas Activity (atau subkelasnya yang ada). Dalam subkelas itu, Anda perlu mengimplementasikan metode-metode callback yang dipanggil sistem saat aktivitas bertransisi di antara berbagai status daur hidupnya, misalnya saat aktivitas sedang dibuat, dihentikan, dilanjutkan, atau dimusnahkan. Dua metode callback terpenting adalah:

onCreate()
Anda harus mengimplementasikan metode ini. Sistem memanggilnya saat membuat aktivitas Anda. Dalam implementasi, Anda harus melakukan inisialiasi komponen-komponen esensial aktivitas. Yang terpenting, inilah tempat Anda harus memanggil setContentView() untuk mendefinisikan layout untuk antarmuka pengguna aktivitas.
onPause()
Sistem memanggil metode ini sebagai pertanda pertama bahwa pengguna sedang meninggalkan aktivitas Anda (walau itu tidak selalu berarti aktivitas sedang dimusnahkan). Inilah biasanya tempat Anda harus mengikat setiap perubahan yang harus dipertahankan selepas sesi pengguna saat ini (karena pengguna mungkin tidak kembali).

Ada beberapa metode callback daur hidup lainnya yang harus Anda gunakan untuk memberikan pengalaman pengguna yang mengalir di antara aktivitas dan menangani interupsi tidak terduga yang menyebabkan aktivitas Anda dihentikan dan bahkan dimusnahkan. Semua metode callback daur hidup akan dibahas nanti, di bagian tentang Mengelola Daur Hidup Aktivitas.

Mengimplementasikan antarmuka pengguna

Antarmuka pengguna aktivitas disediakan oleh hierarki objek—tampilan yang diturunkan dari kelas View. Tiap tampilan mengontrol sebuah ruang persegi panjang tertentu dalam jendela aktivitas dan bisa merespons interaksi pengguna. Misalnya, sebuah tampilan mungkin berupa sebuah tombol yang mengawali suatu aksi bila pengguna menyentuhnya.

Android menyediakan sejumlah tampilan siap-dibuat yang bisa Anda gunakan untuk mendesain dan mengatur layout. "Widget" adalah tampilan yang menyediakan elemen-elemen visual (dan interaktif) untuk layar, misalnya tombol, bidang teks, kotak centang, atau sekadar sebuah gambar. "Layout" adalah tampilan yang berasal dari ViewGroup yang menyediakan sebuah model layout unik untuk tampilan anaknya, misalnya layout linier, layout petak, atau layout relatif. Anda juga bisa mensubkelaskan kelas-kelas View dan ViewGroup (atau subkelas yang ada) untuk membuat widget dan layout Anda sendiri dan menerapkannya ke layout aktivitas Anda.

Cara paling umum untuk mendefinisikan layout dengan menggunakan tampilan adalah dengan file layout XML yang disimpan dalam sumber daya aplikasi Anda. Dengan cara ini, Anda bisa memelihara desain antarmuka pengguna Anda secara terpisah dari kode sumber yang mendefinisikan perilaku aktivitas. Anda bisa mengatur layout sebagai UI aktivitas Anda dengan setContentView(), dengan meneruskan ID sumber daya untuk layout itu. Akan tetapi, Anda juga bisa membangun View baru dalam kode aktivitas dan membangun hierarki tampilan dengan menyisipkan View baru ke dalam ViewGroup, kemudian menggunakan layout itu dengan meneruskan akar ViewGroup ke setContentView().

Untuk informasi tentang cara membuat antarmuka pengguna, lihat dokumentasi Antarmuka Pengguna.

Mendeklarasikan aktivitas dalam manifes

Anda harus mendeklarasikan aktivitas dalam file manifes agar file itu bisa diakses oleh sistem. Untuk mendeklarasikan aktivitas, bukalah file manifes Anda dan tambahkan sebuah elemen <activity> sebagai anak elemen <application>. Misalnya:

<manifest ... >
  <application ... >
      <activity android:name=".ExampleActivity" />
      ...
  </application ... >
  ...
</manifest >

Ada beberapa atribut lain yang bisa Anda sertakan dalam elemen ini, untuk mendefinisikan properti seperti label untuk aktivitas, ikon untuk aktivitas, atau tema untuk memberi gaya pada UI aktivitas. android:name adalah satu-satunya atribut yang diperlukan—atribut ini menetapkan nama kelas aktivitas. Setelah mempublikasikan aplikasi, Anda tidak boleh mengubah nama ini, karena jika melakukannya, Anda bisa merusak sebagian fungsionalitas, misalnya pintasan aplikasi (bacalah entri blog berjudul Things That Cannot Change).

Lihat referensi elemen <activity> untuk informasi selengkapnya tentang mendeklarasikan aktivitas Anda dalam manifes.

Menggunakan filter maksud

Elemen <activity> juga bisa menetapkan beragam filter maksud—dengan menggunakan elemen <intent-filter>—untuk mendeklarasikan cara komponen aplikasi lain mengaktifkannya.

Bila Anda membuat aplikasi baru dengan Android SDK Tools, aktivitas stub yang dibuat untuk Anda secara otomatis menyertakan filter maksud yang mendeklarasikan respons aktivitas pada aksi "main" (utama) dan harus diletakkan dalam kategori "launcher" (peluncur). Filter maksud terlihat seperti ini:

<activity android:name=".ExampleActivity" android:icon="@drawable/app_icon">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Elemen <action> menetapkan bahwa ini adalah titik masuk "utama" ke aplikasi. Elemen <category> menetapkan bahwa aktivitas ini harus tercantum dalam peluncur aplikasi sistem (untuk memungkinkan pengguna meluncurkan aktivitas ini).

Jika Anda bermaksud agar aplikasi dimuat dengan sendirinya dan tidak memperbolehkan aplikasi lain mengaktifkan aktivitasnya, maka Anda tidak memerlukan filter maksud lain. Hanya satu aktivitas yang boleh memiliki aksi "main" dan kategori "launcher", seperti dalam contoh sebelumnya. Aktivitas yang tidak ingin Anda sediakan untuk aplikasi lain tidak boleh memiliki filter maksud dan Anda bisa memulai sendiri aktivitas dengan menggunakan maksud secara eksplisit (seperti dibahas di bagian berikut).

Akan tetapi, jika ingin aktivitas Anda merespons maksud implisit yang dikirim dari aplikasi lain (dan aplikasi Anda sendiri), maka Anda harus mendefinisikan filter maksud tambahan untuk aktivitas. Untuk masing-masing tipe maksud yang ingin direspons, Anda harus menyertakan sebuah <intent-filter> yang menyertakan elemen <action> dan, opsional, sebuah elemen <category> dan/atau elemen <data>. Elemen-elemen ini menetapkan tipe maksud yang bisa direspons oleh aktivitas Anda.

Untuk informasi selengkapnya tentang cara aktivitas Anda merespons maksud, lihat dokumen Maksud dan Filter Maksud.

Memulai Aktivitas

Anda bisa memulai aktivitas lain dengan memanggil startActivity(), dengan meneruskan sebuah Intent yang menjelaskan aktivitas yang ingin Anda mulai. Maksud menetapkan aktivitas persis yang ingin Anda mulai atau menjelaskan tipe aksi yang ingin Anda lakukan (dan sistem akan memilih aktivitas yang sesuai untuk Anda, yang bahkan bisa berasal dari aplikasi berbeda). Maksud juga bisa membawa sejumlah kecil data untuk digunakan oleh aktivitas yang dimulai.

Saat bekerja dalam aplikasi sendiri, Anda nanti akan sering meluncurkan aktivitas yang dikenal saja. Anda bisa melakukannya dengan membuat maksud yang mendefinisikan secara eksplisit aktivitas yang ingin Anda mulai, dengan menggunakan nama kelas. Misalnya, beginilah cara satu aktivitas memulai aktivitas lain bernama SignInActivity:

Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);

Akan tetapi, aplikasi Anda mungkin juga perlu melakukan beberapa aksi, misalnya mengirim email, pesan teks, atau pembaruan status, dengan menggunakan data dari aktivitas Anda. Dalam hal ini, aplikasi Anda mungkin tidak memiliki aktivitasnya sendiri untuk melakukan tindakan tersebut, sehingga Anda bisa memanfaatkan aktivitas yang disediakan oleh aplikasi lain pada perangkat, yang bisa melakukan tindakan itu untuk Anda. Inilah saatnya maksud benar-benar berharga—Anda bisa membuat maksud yang menjelaskan aksi yang ingin dilakukan dan sistem akan meluncurkan aktivitas yang tepat dari aplikasi lain. Jika ada beberapa aktivitas yang bisa menangani maksud itu, pengguna bisa memilih aktivitas yang akan digunakan. Misalnya, jika Anda ingin memperbolehkan pengguna mengirim pesan email, Anda bisa membuat maksud berikut:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

Ekstra EXTRA_EMAIL yang ditambahkan ke maksud adalah sebuah larik string alamat email yang menjadi tujuan pengiriman email. Bila aplikasi email merespons maksud ini, aplikasi itu akan membaca larik string yang disediakan dalam ekstra dan meletakkannya dalam bidang "to" pada formulir penulisan email. Dalam situasi ini, aktivitas aplikasi email dimulai dan bila pengguna selesai, aktivitas Anda akan dilanjutkan.

Memulai aktivitas agar berhasil

Kadang-kadang, Anda mungkin ingin menerima hasil dari aktivitas yang Anda mulai. Dalam hal itu, mulailah aktivitas dengan memanggil startActivityForResult() (sebagai ganti startActivity()). Untuk menerima hasil dari aktivitas selanjutnya nanti, implementasikan metode callback onActivityResult() . Bila aktivitas selanjutnya selesai, aktivitas akan mengembalikan hasil dalam Intent ke metode onActivityResult() Anda.

Misalnya, mungkin Anda ingin pengguna mengambil salah satu kontaknya, sehingga aktivitas Anda bisa melakukan sesuatu dengan informasi dalam kontak itu. Begini caranya membuat maksud tersebut dan menangani hasilnya:

private void pickContact() {
    // Create an intent to "pick" a contact, as defined by the content provider URI
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Perform a query to the contact's content provider for the contact's name
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // True if the cursor is not empty
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Do something with the selected contact's name...
        }
    }
}

Contoh ini menunjukkan logika dasar yang harus Anda gunakan dalam metode onActivityResult() Anda untuk menangani hasil aktivitas. Ketentuan pertama memeriksa apakah permintaan berhasil—jika ya, maka resultCode akan berupa RESULT_OK—dan apakah permintaan yang direspons hasil ini dikenali—dalam hal ini, requestCode cocok dengan parameter kedua yang dikirim dengan startActivityForResult(). Dari sana, kode akan menangani hasil aktivitas dengan melakukan kueri atas data yang dikembalikan dalam Intent (parameter data).

Yang terjadi adalah ContentResolver melakukan kueri terhadap penyedia materi, yang mengembalikan Cursor dan memungkinkan data kueri dibaca. Untuk informasi selengkapnya, lihat dokumen Penyedia Materi.

Untuk informasi selengkapnya tentang menggunakan maksud, lihat dokumen Maksud dan Filter Maksud.

Mematikan Aktivitas

Anda bisa mematikan aktivitas dengan memanggil metode finish()-nya. Anda juga bisa mematikan aktivitas terpisah yang sebelumnya Anda mulai dengan memanggil finishActivity().

Catatan: Pada umumnya, Anda tidak boleh secara eksplisit mengakhiri aktivitas dengan menggunakan metode-metode ini. Seperti yang dibahas di bagian berikut tentang daur hidup aktivitas, sistem Android mengelola hidup aktivitas untuk Anda, sehingga Anda tidak perlu menyelesaikan sendiri aktivitas tersebut. Memanggil metode-metode ini bisa berpengaruh negatif pada pengalaman pengguna yang diharapkan dan hanya boleh digunakan bila Anda benar-benar tidak ingin pengguna kembali ke instance aktivitas ini.

Mengelola Daur Hidup Aktivitas

Mengelola daur hidup aktivitas dengan mengimplementasikan metode-metode callback sangat penting untuk mengembangkan aplikasi yang kuat dan fleksibel. Daur hidup aktivitas dipengaruhi langsung oleh kaitannya dengan aktivitas lain, tugasnya, serta back-stack.

Pada dasarnya, sebuah aktivitas bisa berada dalam tiga status:

Dilanjutkan
Aktivitas berada di latar depan layar dan mendapatkan fokus pengguna. (Status ini kadang-kadang disebut juga dengan "running" (berjalan).)
Dihentikan sementara
Aktivitas lain berada di latar depan dan mendapat fokus, namun aktivitas ini masih terlihat. Yakni, aktivitas lain terlihat di atas aplikasi ini dan aktivitas itu setengah transparan atau tidak menuutpi seluruh layar. Aktivitas yang dihentikan sementara adalah benar-benar hidup (objek Activity dipertahankan dalam memori, objek itu memelihara semua informasi status dan anggota, dan tetap dikaitkan dengan window manager), namun bisa dimatikan oleh sistem dalam situasi memori sangat rendah.
Dihentikan
Aktivitas ditutupi sepenuhnya oleh aktivitas lain (aktivitas sekarang berada di "latar belakang"). Aktivitas yang dihentikan juga masih hidup (objek Activity dipertahankan dalam memori, objek itu menjaga semua informasi status dan anggota, namun tidak dikaitkan dengan window manager). Akan tetapi, aktivitas tidak lagi terlihat bagi pengguna dan bisa dimatikan oleh sistem bila memori diperlukan di lain.

Jika aktivitas dihentikan sementara atau dihentikan, sistem bisa mengeluarkannya dari memori baik dengan memintanya agar diakhiri (memanggil metode finish()-nya), atau sekadar mematikan prosesnya. Bila dibuka lagi (setelah diakhiri atau dimatikan), aktivitas harus dibuat dari awal.

Mengimplementasikan callback daur hidup

Saat bertransisi ke dalam dan ke luar berbagai status yang dijelaskan di atas, aktivitas diberi tahu melalui berbagai metode callback. Semua metode callback adalah sangkutan yang bisa Anda ganti untuk melakukan pekerjaan yang sesuai saat status aktivitas Anda berubah. Aktivitas skeleton berikut menyertakan setiap metode daur hidup mendasar:

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // The activity is being created.
    }
    @Override
    protected void onStart() {
        super.onStart();
        // The activity is about to become visible.
    }
    @Override
    protected void onResume() {
        super.onResume();
        // The activity has become visible (it is now "resumed").
    }
    @Override
    protected void onPause() {
        super.onPause();
        // Another activity is taking focus (this activity is about to be "paused").
    }
    @Override
    protected void onStop() {
        super.onStop();
        // The activity is no longer visible (it is now "stopped")
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // The activity is about to be destroyed.
    }
}

Catatan: Implementasi Anda terhadap metode-metode daur hidup ini harus selalu memanggil implementasi superkelas sebelum melakukan pekerjaan apa pun, seperti yang ditampilkan dalam contoh-contoh di atas.

Bersama-sama, semua metode ini mendefinisikan seluruh daur hidup sebuah aktivitas. Dengan mengimplementasikan metode-metode ini, Anda bisa memantau tiga loop tersarang (nested loop) dalam daur hidup aktivitas:

  • Masa pakai keseluruhan aktivitas berlangsung antara panggilan ke onCreate() dan panggilan ke onDestroy(). Aktivitas Anda harus melakukan penyiapan status "global" (misalnya mendefinisikan layout) dalam onCreate(), dan melepas semua sisa sumber daya dalam onDestroy(). Misalnya, jika aktivitas Anda memiliki sebuah thread yang berjalan di latar belakang untuk mengunduh data dari jaringan, aktivitas itu bisa membuat thread itu dalam onCreate() kemudian menghentikan thread dalam onDestroy().
  • Masa pakai terlihat aktivitas berlangsung antara panggilan ke onStart() dan panggilan ke onStop(). Selama ini, pengguna bisa melihat aktivitas pada layar dan berinteraksi dengannya. Misalnya, onStop() dipanggil bila sebuah aktivitas baru dimulai dan aktivitas ini tidak lagi terlihat. Di antara dua metode ini, Anda bisa memelihara sumber daya yang diperlukan untuk menampilkan aktivitas kepada pengguna. Misalnya, Anda bisa mendaftarkan sebuah BroadcastReceiver dalam onStart() untuk memantau perubahan yang berdampak pada UI Anda, dan mencabut pendaftarannya dalam onStop() bila pengguna tidak bisa lagi melihat apa yang sedang Anda tampilkan. Sistem bisa memanggil onStart() dan onStop() beberapa kali selama masa pakai keseluruhan aktivitas, saat aktivitas silih berganti antara terlihat dan tersembunyi bagi pengguna.

  • Masa pakai latar depan aktivitas berlangsung antara panggilan ke onResume() dan panggilan ke onPause(). Selama waktu ini, aktivitas berada di depan semua aktivitas lain pada layar dan mendapatkan fokus masukan pengguna. Aktivitas bisa sering bertransisi ke dalam dan ke luar latar depan—misalnya, onPause() dipanggil bila perangkat masuk ke mode tidur atau bila dialog muncul. Karena status ini bisa sering bertransisi, kode dalam dua metode ini harus cukup ringan untuk menghindari transisi lamban yang membuat pengguna menunggu.

Gambar 1 mengilustrasikan loop dan jalur yang mungkin diambil sebuah aktivitas di antara status-status. Persegi panjang mewakili metode callback yang bisa Anda implementasikan untuk melakukan operasi saat aktivitas bertransisi di antara status.

Gambar 1. Daur hidup aktivitas.

Metode-metode callback daur hidup yang sama tercantum dalam tabel 1, yang menjelaskan setiap metode callback secara lebih detail dan menentukan lokasinya masing-masing dalam daur hidup aktivitas keseluruhan, termasuk apakah sistem bisa mematikan aktivitas setelah metode callback selesai.

Tabel 1. Rangkuman metode callback daur hidup aktivitas.

Metode Keterangan Bisa dimatikan setelahnya? Berikutnya
onCreate() Dipanggil saat aktivitas pertama kali dibuat. Di sinilah Anda harus melakukan semua persiapan statis normal — membuat tampilan, mengikat data ke daftar, dan sebagainya. Metode ini diberi sebuah objek Bundle yang berisi status aktivitas sebelumnya, jika status itu tertangkap (lihat Menyimpan Status Aktivitas, nanti).

Selalu diikuti oleh onStart().

Tidak onStart()
     onRestart() Dipanggil setelah aktivitas dihentikan, tepat sebelum dimulai lagi.

Selalu diikuti oleh onStart()

Tidak onStart()
onStart() Dipanggil tepat sebelum aktivitas menjadi terlihat bagi pengguna.

Diikuti oleh onResume() jika aktivitas maju ke latar depan, atau onStop() jika menjadi tersembunyi.

Tidak onResume()
atau
onStop()
     onResume() Dipanggil tepat sebelum aktivitas mulai berinteraksi dengan pengguna. Pada titik ini, aktivitas berada di puncak tumpukan aktivitas, dengan masukan pengguna menuju kepadanya.

Selalu diikuti oleh onPause().

Tidak onPause()
onPause() Dipanggil bila sistem akan mulai melanjutkan aktivitas lain. Metode ini biasanya digunakan untuk menerapkan (commit) perubahan yang tidak tersimpan pada data persisten, menghentikan animasi dan hal-hal lain yang mungkin menghabiskan CPU, dan sebagainya. Metode ini harus melakukan apa saja yang dilakukannya dengan sangat cepat, karena aktivitas berikutnya tidak akan dilanjutkan hingga aktivitas ini kembali.

Diikuti oleh onResume() jika aktivitas kembali ke depan, atau oleh onStop() jika menjadi tidak terlihat bagi pengguna.

Ya onResume()
atau
onStop()
onStop() Dipanggil bila aktivitas tidak lagi terlihat bagi pengguna. Hal ini bisa terjadi karena aktivitas sedang dimusnahkan, atau karena aktivitas lain (aktivitas yang ada atau yang baru) telah dilanjutkan dan sedang menutupinya.

Diikuti oleh onRestart() jika aktivitas kembali untuk berinteraksi dengan pengguna, atau oleh onDestroy() jika aktivitas ini akan menghilang.

Ya onRestart()
atau
onDestroy()
onDestroy() Dipanggil sebelum aktivitas dimusnahkan. Inilah panggilan terakhir yang akan diterima aktivitas. Metode ini bisa dipanggil karena aktivitas selesai (seseorang memanggil finish() padanya), atau karena sistem memusnahkan sementara instance aktivitas ini untuk menghemat tempat. Anda bisa membedakan kedua skenario ini dengan metode isFinishing(). Ya tidak ada

Kolom berlabel "Bisa dimatikan setelahnya?" menunjukkan apakah sistem bisa atau tidak mematikan proses yang menjadi host aktivitas kapan saja setelah metode kembali, tanpa menjalankan baris lain pada kode aktivitas. Tiga metode ini ditandai "ya": (onPause(), onStop(), dan onDestroy()). Karena onPause() adalah yang pertama dari tiga, begitu aktivitas dibuat, onPause() adalah metode terakhir yang dipastikan akan dipanggil sebelum proses bisa dimatikan—jika sistem harus memulihkan memori dalam keadaan darurat, maka onStop() dan onDestroy() mungkin tidak dipanggil. Karena itu, Anda harus menggunakan onPause() untuk menulis data persisten yang penting (misalnya hasil edit pengguna) ke storage. Akan tetapi, Anda harus selektif dalam hal informasi yang harus dipertahankan selama onPause(), karena setiap prosedur pemblokiran dalam metode ini akan memblokir transisi ke aktivitas berikutnya dan memperlambat pengalaman pengguna.

Metode-metode yang ditandai "Tidak" dalam kolom Bisa dimatikan melindungi proses yang menjadi host aktivitas dari dimatikan sejak saat metode dipanggil. Jadi, aktivitas bisa dimatikan sejak onPause() kembali hingga waktu onResume() dipanggil. Aktivitas tidak akan lagi bisa dimatikan hingga onPause() dipanggil lagi dan kembali.

Catatan: Aktivitas yang tidak "bisa dimatikan" secara teknis oleh definisi dalam tabel 1 masih bisa dimatikan oleh sistem—namun itu hany terjadi dalam situasi ekstrem bila tidak ada jalan lain. Kapan aktivitas bisa dimatikan akan dibahas selengkapnya dalam dokumen Proses dan Threading.

Menyimpan status aktivitas

Pengantar untuk Mengelola Daur Hidup Aktivitas secara ringkas menyebutkan bahwa bila aktivitas dihentikan sementara atau dihentikan, status aktivitas akan dipertahankan. Hal itu terjadi karena objek Activity masih ditahan dalam memori saat aktivitas dihentikan sementara atau dihentikan—semua informasi tentang anggota dan statusnya saat ini masih hidup. Jadi, setiap perubahan yang dibuat pengguna dalam aktivitas akan dipertahankan sehingga bila aktivitas kembali ke latar depan (bila "dilanjutkan"), perubahan itu masih ada.

Akan tetapi, bila sistem memusnahkan aktivitas untuk memulihkan memori, objek Activity akan dimusnahkan, sehingga sistem tidak bisa begitu saja melanjutkan aktivitas dengan status tidak berubah. Sebagai gantinya, sistem harus membuat ulang objek Activity jika pengguna menyusuri kembali ke aktivitas tersebut. Namun, pengguna tidak menyadari bahwa sistem memusnahkan aktivitas dan membuatnya kembali dan, karena itu, mungkin mengharapkan aktivitas untuk sama persis dengan sebelumnya. Dalam situasi ini, Anda bisa memastikan bahwa informasi penting tentang status aktivitas tetap terjaga dengan mengimplementasikan metode callback tambahan yang memungkinkan Anda menyimpan informasi tentang status aktivitas: onSaveInstanceState().

Sistem memanggil onSaveInstanceState() sebelum membuat aktivitas rawan terhadap pemusnahan. Sistem meneruskan ke metode ini sebuah Bundle tempat Anda bisa menyimpan informasi status tentang aktivitas sebagai pasangan nama-nilai, dengan menggunakan metode-metode misalnya putString() dan putInt(). Kemudian, jika sistem mematikan proses aplikasi Anda dan pengguna menyusuri kembali ke aktivitas tersebut, sistem akan membuat kembali aktivitas dan meneruskan Bundle ke onCreate() maupun onRestoreInstanceState(). Dengan menggunakan salah satu metode ini, Anda bisa mengekstrak status tersimpan dari Bundle dan memulihkan status aktivitas. Jika tidak ada informasi status yang ingin dipulihkan, maka Bundle yang diteruskan kepada Anda akan nol (yang akan terjadi bila aktivitas dibuat untuk pertama kali).

Gambar 2. Ada dua cara yang bisa digunakan aktivitas untuk kembali ke fokus pengguna dengan status tetap: aktivitas dimusnahkan, kemudian dibuat kembali, dan aktivitas harus memulihkan status yang disimpan sebelumnya, atau aktivitas dihentikan, kemudian dilanjutkan dengan status aktivitas tetap.

Catatan: Tidak ada jaminan bahwa onSaveInstanceState() akan dipanggil sebelum aktivitas Anda dimusnahkan, karena bisa saja terjadi aktivitas tidak perlu menyimpan status (misalnya saat pengguna meninggalkan aktivitas dengan menggunakan tombol Kembali, karena pengguna menutup aktivitas secara eksplisit ). Jika sistem memanggil onSaveInstanceState(), ini akan dilakukan sebelum onStop() dan mungkin sebelum onPause().

Akan tetapi, sekalipun Anda tidak melakukan apa-apa dan tidak mengimplementasikan onSaveInstanceState(), beberapa status aktivitas akan dipulihkan oleh implementasi default onSaveInstanceState() kelas Activity. Khususnya, implementasi default akan memanggil metode onSaveInstanceState() yang sesuai untuk setiap View dalam layout, yang memungkinkan setiap tampilan menyediakan informasi tentang dirinya sendiri yang harus disimpan. Hampir setiap widget dalam kerangka kerja Android mengimplementasikan metode ini sebagaimana mestinya, sehingga setiap perubahan yang terlihat pada UI akan disimpan dan dipulihkan secara otomatis bila aktivitas Anda dibuat kembali. Misalnya, widget EditText menyimpan teks apa saja yang dimasukkan oleh pengguna dan widget CheckBox menyimpan baik teks itu diperiksa maupun tidak. Satu-satunya pekerjaan yang Anda perlukan adalah menyediakan ID unik (dengan atribut android:id) untuk masing-masing widget yang ingin disimpan statusnya. Jika widget tidak memiliki ID, maka sistem tidak bisa menyimpan statusnya.

Walaupun implementasi default onSaveInstanceState() menyimpan informasi yang berguna tentang UI aktivitas, Anda mungkin masih perlu menggantinya untuk menyimpan informasi tambahan. Misalnya, Anda mungkin perlu menyimpan nilai-nilai anggota yang berubah selama masa pakai aktivitas (yang mungkin berkorelasi dengan nilai-nilai yang dipulihkan dalam UI, namun anggota-anggota yang menyimpan nilai-nilai UI itu secara default tidak dipulihkan).

Karena implementasi default onSaveInstanceState() membantu menyimpan status UI, jika Anda mengganti metode ini untuk menyimpan informasi status tambahan, Anda harus selalu memanggil implementasi superkelas onSaveInstanceState() sebelum melakukan pekerjaan apa pun. Demikian pula, Anda juga harus memanggil implementasi superkelas onRestoreInstanceState() jika menggantinya, sehingga implementasi default bisa memulihkan status tampilan.

Catatan: Karena onSaveInstanceState() tidak dijamin akan dipanggil, Anda harus menggunakannya hanya untuk mencatat status aktivitas sementara (transient) (status UI)—Anda tidak boleh menggunakannya untuk menyimpan data persisten. Sebagai gantinya, Anda harus menggunakan onPause() untuk menyimpan data persisten (misalnya data yang harus disimpan ke database) saat pengguna meninggalkan aktivitas.

Salah satu cara yang baik untuk menguji kemampuan aplikasi dalam memulihkan statusnya adalah cukup dengan memutar perangkat sehingga orientasi layarnya berubah. Bila orientasi layar berubah, sistem akan memusnahkan dan membuat kembali aktivitas untuk menerapkan sumber daya alternatif yang mungkin tersedia untuk konfigurasi layar baru. Karena alasan ini saja, sangat penting bahwa aktivitas Anda memulihkan statusnya secara lengkap saat dibuat kembali, karena pengguna memutar layar secara rutin saat menggunakan aplikasi.

Menangani perubahan konfigurasi

Sebagian konfigurasi perangkat bisa berubah saat waktu proses (misalnya orientasi layar, ketersediaan keyboard , dan bahasa). Bila terjadi perubahan demikian, Android akan membuat kembali aktivitas yang berjalan (sistem akan memanggil onDestroy(), kemudian segera memanggil onCreate(). Perilaku ini didesain untuk membantu aplikasi Anda menyesuaikan diri dengan konfigurasi baru dengan cara memuat ulang aplikasi Anda secara otomatis dengan sumber daya alternatif yang telah Anda sediakan (misalnya layout yang berbeda untuk layar orientasi dan ukuran yang berbeda).

Jika Anda mendesain aktivitas dengan benar untuk menangani mulai ulang karena perubahan orientasi layar dan memulihkan status aktivitas seperti yang dijelaskan di atas, aplikasi Anda akan lebih tahan terhadap kejadian tidak terduga lainnya dalam daur hidup aktivitas.

Cara terbaik menangani mulai ulang tersebut adalah menyimpan dan memulihkan status aktivitas Anda dengan menggunakan onSaveInstanceState() dan onRestoreInstanceState() (atau onCreate()), seperti yang dibahas di bagian sebelumnya.

Untuk informasi selengkapnya tentang konfigurasi perubahan yang terjadi saat program berjalan dan cara menanganinya , bacalah panduan untuk Menangani Perubahan Waktu Proses.

Mengoordinasikan aktivitas

Bila suatu aktivitas memulai aktivitas lain, keduanya akan mengalami transisi daur hidup. Aktivitas pertama akan berhenti sementara dan berhenti sama sekali (walau tidak akan berhenti jika masih terlihat di latar belakang), saat aktivitas lain dibuat. Jika aktivitas-aktivitas ini berbagi data yang disimpan ke disk atau di tempat lain, Anda perlu memahami bahwa aktivitas pertama tidak dihentikan sepenuhnya sebelum aktivitas kedua dibuat. Sebagai gantinya, proses akan memulai aktivitas kedua secara tumpang tindih dengan proses penghentian aktivitas pertama.

Urutan callback daur hidup didefinisikan dengan baik, khususnya bila kedua aktivitas berada dalam proses yang sama dan salah satunya memulai yang lain. Berikut ini adalah urutan operasi yang terjadi bila Aktivitas A memulai Aktivitas B:

  1. Metode onPause() Aktivitas A berjalan.
  2. Metode onCreate(), onStart(), dan onResume() aktivitas B dieksekusi secara berurutan. (Aktivitas B sekarang mendapatkan fokus pengguna.)
  3. Kemudian, jika Aktivitas A tidak lagi terlihat di layar, metode onStop()-nya akan dieksekusi.

Urutan callback daur hidup yang bisa diramalkan ini memungkinkan Anda mengelola transisi informasi dari satu aktivitas ke aktivitas lainnya. Misalnya, jika Anda harus menulis ke database saat aktivitas pertama berhenti agar aktivitas berikutnya bisa membacanya, maka Anda harus menulis ke database selama onPause() sebagai ganti selama onStop().