Saat pengguna menelusuri, keluar, dan kembali ke aplikasi Anda, instance Activity
dalam aplikasi Anda melakukan transisi ke berbagai status dalam siklus prosesnya.
Class Activity
menyediakan sejumlah callback
yang memungkinkan aktivitas mengetahui kapan status berubah atau bahwa
sistem membuat, menghentikan, atau melanjutkan aktivitas atau mengakhiri
proses tempat aktivitas berada.
Dalam metode callback siklus proses, Anda dapat mendeklarasikan cara aktivitas berperilaku saat pengguna meninggalkan dan memasuki kembali aktivitas itu. Misalnya, jika mem-build pemutar video streaming, Anda dapat menjeda video dan mengakhiri koneksi jaringan saat pengguna beralih ke aplikasi lain. Saat pengguna kembali, Anda dapat menghubungkan kembali ke jaringan dan membiarkan pengguna melanjutkan video dari tempat yang sama.
Setiap callback memungkinkan Anda melakukan pekerjaan tertentu yang sesuai dengan perubahan status tertentu. Melakukan pekerjaan yang tepat dan pada waktu yang tepat, serta menangani transisi dengan benar membuat aplikasi Anda lebih andal dan efektif. Misalnya, implementasi callback siklus proses yang baik dapat membantu aplikasi Anda menghindari hal berikut:
- Error jika pengguna menerima panggilan telepon atau beralih ke aplikasi lain selagi menggunakan aplikasi Anda.
- Penggunaan resource sistem yang berharga jika pengguna tidak secara aktif menggunakannya.
- Kehilangan progres pengguna jika mereka keluar dari aplikasi Anda dan kembali lagi nanti.
- Error atau kehilangan progres pengguna ketika layar berputar antara orientasi lanskap dan potret.
Dokumen ini menjelaskan siklus proses aktivitas secara detail. Dokumen dimulai dengan menjelaskan paradigma siklus proses. Selanjutnya, dokumen menjelaskan setiap callback: apa yang terjadi secara internal saat callback mengeksekusi dan apa yang perlu Anda terapkan selama callback tersebut.
Selanjutnya, dokumen tersebut secara singkat memperkenalkan hubungan antara status aktivitas dan kerentanan suatu proses akan ditutup oleh sistem. Terakhir, bagian ini membahas beberapa topik yang terkait dengan transisi antarstatus aktivitas.
Untuk informasi tentang penanganan siklus proses, termasuk panduan tentang praktik terbaik, lihat Menangani Siklus Proses dengan Komponen Berbasis Siklus Proses dan Menyimpan status UI. Untuk mempelajari cara merancang aplikasi yang tangguh dan berkualitas produksi menggunakan aktivitas yang dikombinasikan dengan komponen arsitektur, lihat Panduan untuk arsitektur aplikasi.
Konsep siklus proses aktivitas
Untuk menavigasi transisi di antara tahap siklus proses aktivitas, class
Activity
menyediakan kumpulan inti enam callback:
onCreate()
,
onStart()
,
onResume()
,
onPause()
,
onStop()
, dan
onDestroy()
. Sistem memanggil
setiap callback ini saat aktivitas memasuki status baru.
Gambar 1 menyajikan representasi visual dari paradigma ini.
![](https://developer.android.google.cn/guide/components/images/activity_lifecycle.png?authuser=19&hl=id)
Gambar 1. Ilustrasi sederhana dari siklus proses aktivitas.
Setelah pengguna mulai meninggalkan aktivitas, sistem memanggil metode untuk membongkar aktivitas. Pada beberapa kasus, aktivitas hanya terbuang sebagian dan masih berada dalam memori, seperti saat pengguna beralih ke aplikasi lain. Dalam kasus ini, aktivitas masih dapat kembali ke latar depan.
Jika pengguna kembali ke aktivitas tersebut, aktivitas akan dilanjutkan dari bagian terakhir yang ditinggalkan pengguna. Dengan beberapa pengecualian, aplikasi dibatasi agar tidak memulai aktivitas saat berjalan di latar belakang.
Kemungkinan sistem untuk menghentikan proses tertentu, bersama dengan aktivitas di dalamnya, bergantung pada status aktivitas pada saat itu. Untuk informasi selengkapnya tentang hubungan antara status dan kerentanan terhadap ejeksi, lihat bagian tentang status aktivitas dan ejeksi dari memori.
Bergantung pada kompleksitas aktivitas, Anda mungkin tidak perlu mengimplementasikan semua metode siklus proses. Namun, penting bagi Anda memahami masing-masing dan menerapkan hal yang membuat aplikasi Anda berperilaku seperti yang diharapkan pengguna.
Callback siklus proses
Bagian ini memberikan informasi konseptual dan implementasi tentang metode callback yang digunakan selama siklus proses aktivitas.
Beberapa tindakan termasuk dalam metode siklus proses aktivitas. Namun, tempatkan kode yang mengimplementasikan tindakan komponen dependen dalam komponen, bukan metode siklus proses aktivitas. Untuk mencapai ini, Anda harus membuat komponen dependen berbasis siklus proses. Untuk mempelajari cara membuat komponen dependen berbasis siklus proses, lihat Menangani Siklus Proses dengan Komponen Berbasis Siklus Proses.
onCreate()
Anda harus menerapkan callback ini, yang aktif saat sistem pertama kali membuat aktivitas. Pada pembuatan aktivitas, aktivitas memasuki status Dibuat.
Dalam metode onCreate()
, jalankan logika startup aplikasi dasar yang
hanya terjadi sekali selama masa aktif aktivitas.
Misalnya, implementasi
onCreate()
Anda dapat mengikat data ke daftar, mengaitkan aktivitas dengan
ViewModel
,
dan membuat instance beberapa variabel cakupan class. Metode ini menerima
parameter savedInstanceState
, yang merupakan objek Bundle
yang berisi status aktivitas yang disimpan sebelumnya. Jika aktivitas belum pernah ada sebelumnya, nilai objek Bundle
adalah null.
Jika Anda memiliki komponen berbasis siklus proses yang terhubung dengan siklus proses
aktivitas Anda, komponen tersebut akan menerima
peristiwa
ON_CREATE
. Metode yang dianotasi dengan @OnLifecycleEvent
dipanggil sehingga komponen berbasis siklus proses
dapat menjalankan kode penyiapan apa pun yang diperlukan untuk status yang dibuat.
Contoh metode onCreate()
berikut
menunjukkan penyiapan dasar untuk aktivitas tersebut, seperti mendeklarasikan antarmuka pengguna
(ditentukan dalam file tata letak XML), menentukan variabel anggota, dan mengonfigurasi
beberapa UI. Dalam contoh ini, file tata letak XML meneruskan
ID resource file R.layout.main_activity
ke
setContentView()
.
Kotlin
lateinit var textView: TextView // Some transient state for the activity instance. var gameState: String? = null override fun onCreate(savedInstanceState: Bundle?) { // Call the superclass onCreate to complete the creation of // the activity, like the view hierarchy. super.onCreate(savedInstanceState) // Recover the instance state. gameState = savedInstanceState?.getString(GAME_STATE_KEY) // Set the user interface layout for this activity. // The layout is defined in the project res/layout/main_activity.xml file. setContentView(R.layout.main_activity) // Initialize member TextView so it is available later. textView = findViewById(R.id.text_view) } // This callback is called only when there is a saved instance previously saved using // onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally // be restored here, possibly usable after onStart() has completed. // The savedInstanceState Bundle is same as the one used in onCreate(). override fun onRestoreInstanceState(savedInstanceState: Bundle?) { textView.text = savedInstanceState?.getString(TEXT_VIEW_KEY) } // Invoked when the activity might be temporarily destroyed; save the instance state here. override fun onSaveInstanceState(outState: Bundle?) { outState?.run { putString(GAME_STATE_KEY, gameState) putString(TEXT_VIEW_KEY, textView.text.toString()) } // Call superclass to save any view hierarchy. super.onSaveInstanceState(outState) }
Java
TextView textView; // Some transient state for the activity instance. String gameState; @Override public void onCreate(Bundle savedInstanceState) { // Call the superclass onCreate to complete the creation of // the activity, like the view hierarchy. super.onCreate(savedInstanceState); // Recover the instance state. if (savedInstanceState != null) { gameState = savedInstanceState.getString(GAME_STATE_KEY); } // Set the user interface layout for this activity. // The layout is defined in the project res/layout/main_activity.xml file. setContentView(R.layout.main_activity); // Initialize member TextView so it is available later. textView = (TextView) findViewById(R.id.text_view); } // This callback is called only when there is a saved instance previously saved using // onSaveInstanceState(). Some state is restored in onCreate(). Other state can optionally // be restored here, possibly usable after onStart() has completed. // The savedInstanceState Bundle is same as the one used in onCreate(). @Override public void onRestoreInstanceState(Bundle savedInstanceState) { textView.setText(savedInstanceState.getString(TEXT_VIEW_KEY)); } // Invoked when the activity might be temporarily destroyed; save the instance state here. @Override public void onSaveInstanceState(Bundle outState) { outState.putString(GAME_STATE_KEY, gameState); outState.putString(TEXT_VIEW_KEY, textView.getText()); // Call superclass to save any view hierarchy. super.onSaveInstanceState(outState); }
Sebagai alternatif untuk menentukan file XML dan meneruskannya ke setContentView()
, Anda
dapat membuat objek View
baru dalam kode aktivitas dan mem-build
hierarki tampilan dengan memasukkan objek View
baru ke dalam
ViewGroup
. Anda kemudian menggunakan tata letak tersebut dengan meneruskan root ViewGroup
ke setContentView()
.
Untuk mengetahui informasi selengkapnya tentang membuat antarmuka pengguna, lihat
dokumentasi antarmuka pengguna.
Aktivitas Anda tidak tetap dalam status Dibuat. Setelah metode onCreate()
menyelesaikan eksekusi, aktivitas memasuki status Dimulai
dan sistem memanggil metode onStart()
dan onResume()
dalam urutan
cepat.
onStart()
Saat aktivitas memasuki status Dimulai, sistem
akan memanggil onStart()
.
Panggilan ini membuat aktivitas terlihat oleh pengguna saat
aplikasi mempersiapkan aktivitas untuk masuk ke latar depan dan menjadi interaktif.
Misalnya, metode ini adalah tempat kode yang mengelola
UI diinisialisasi.
Saat aktivitas berpindah ke status Dimulai, komponen berbasis siklus proses apa pun yang terkait dengan siklus proses aktivitas akan menerima peristiwa ON_START
.
Metode onStart()
selesai dengan cepat dan, seperti pada status Dibuat, aktivitas tidak tetap berada dalam status Dimulai. Setelah callback ini selesai, aktivitas memasuki
status Dilanjutkan dan sistem memanggil
metode onResume()
.
onResume()
Ketika aktivitas memasuki status Dilanjutkan, aktivitas tersebut masuk ke latar depan, dan
sistem memanggil callback
onResume()
. Ini adalah status saat aplikasi berinteraksi dengan pengguna. Aplikasi tetap dalam status ini sampai terjadi sesuatu untuk
mengambil fokus dari aplikasi, seperti perangkat yang menerima panggilan telepon, pengguna
yang bernavigasi ke aktivitas lain, atau layar perangkat mati.
Saat aktivitas berpindah ke status Dilanjutkan, komponen berbasis siklus proses yang terkait dengan siklus proses aktivitas menerima peristiwa ON_RESUME
. Di sinilah komponen siklus proses dapat mengaktifkan fungsi apa pun yang perlu dijalankan saat komponen terlihat dan berada di latar depan, seperti memulai pratinjau kamera.
Saat terjadi peristiwa interupsi, aktivitas memasuki status Dijeda dan sistem memanggil callback onPause()
.
Jika aktivitas kembali ke status Dilanjutkan dari status Dijeda, sistem sekali lagi akan memanggil metode onResume()
. Karena alasan ini, implementasikan
onResume()
untuk menginisialisasi komponen yang Anda rilis selama
onPause()
dan untuk melakukan inisialisasi
lain yang harus terjadi setiap kali aktivitas memasuki status
Dilanjutkan.
Berikut adalah contoh komponen berbasis siklus proses yang mengakses kamera saat
komponen menerima peristiwa ON_RESUME
:
Kotlin
class CameraComponent : LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun initializeCamera() { if (camera == null) { getCamera() } } ... }
Java
public class CameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void initializeCamera() { if (camera == null) { getCamera(); } } ... }
Kode sebelumnya menginisialisasi kamera setelah
LifecycleObserver
menerima peristiwa ON_RESUME
. Namun, dalam mode multi-aplikasi, aktivitas Anda
mungkin sepenuhnya terlihat meskipun dalam status Dijeda. Misalnya, saat
aplikasi berada dalam mode multi-aplikasi dan pengguna mengetuk jendela yang tidak
berisi aktivitas Anda, aktivitas akan berpindah ke status Dijeda.
Jika Anda
ingin kamera hanya aktif saat aplikasi Dilanjutkan (terlihat
dan aktif di latar depan), inisialisasi kamera setelah
peristiwa ON_RESUME
yang ditunjukkan sebelumnya. Jika Anda ingin kamera tetap aktif saat aktivitas Dijeda tetapi terlihat, seperti dalam mode multi-aplikasi, lakukan inisialisasi kamera setelah peristiwa ON_START
.
Namun, mengaktifkan kamera saat aktivitas Dijeda dapat menolak akses ke kamera ke aplikasi yang Dilanjutkan dalam mode multi-aplikasi. Terkadang, Anda perlu membuat kamera tetap aktif saat aktivitas Dijeda, tetapi hal ini sebenarnya dapat menurunkan pengalaman pengguna secara keseluruhan jika Anda melakukannya.
Karena alasan ini, pikirkan baik-baik tentang posisi yang paling tepat dalam siklus proses untuk mengontrol resource sistem bersama dalam konteks mode multi-aplikasi. Untuk mempelajari lebih lanjut cara mendukung mode multi-aplikasi, lihat Dukungan multi-aplikasi.
Terlepas dari peristiwa build-up yang Anda pilih untuk melakukan operasi inisialisasi, pastikan untuk menggunakan peristiwa siklus proses yang sesuai untuk melepaskan resource. Jika Anda menginisialisasi sesuatu setelah peristiwa ON_START
, lepaskan atau hentikan setelah peristiwa ON_STOP
. Jika Anda
melakukan inisialisasi setelah peristiwa ON_RESUME
, lepaskan setelah
peristiwa ON_PAUSE
.
Cuplikan kode sebelumnya menempatkan kode inisialisasi kamera dalam
komponen berbasis siklus proses. Anda dapat memasukkan kode ini langsung ke callback siklus proses aktivitas, seperti onStart()
dan onStop()
, tetapi kami tidak merekomendasikan hal ini. Menambahkan logika ini
ke komponen independen dan berbasis siklus proses memungkinkan Anda menggunakan kembali komponen
di berbagai aktivitas tanpa harus menduplikasi kode. Untuk mempelajari cara membuat komponen berbasis siklus proses, lihat
Menangani Siklus Proses dengan Komponen Berbasis Siklus Proses.
onPause()
Sistem memanggil metode ini sebagai indikasi pertama bahwa pengguna meninggalkan aktivitas Anda, meskipun itu tidak selalu berarti aktivitas sedang dihancurkan. Ini menunjukkan bahwa aktivitas tidak lagi berada di latar depan, tetapi masih terlihat jika pengguna berada dalam mode multi-aplikasi. Ada beberapa alasan mengapa suatu aktivitas dapat memasuki status ini:
- Peristiwa yang mengganggu eksekusi aplikasi, seperti yang dijelaskan di bagian tentang callback onResume(), akan menjeda aktivitas saat ini. Ini adalah kasus yang paling umum.
- Dalam mode multi-aplikasi, hanya satu aplikasi yang memiliki fokus pada waktu tertentu, dan sistem akan menjeda semua aplikasi lainnya.
- Pembukaan aktivitas semi-transparan baru, seperti dialog, menjeda aktivitas yang dicakup. Selama aktivitas terlihat sebagian tetapi tidak dalam fokus, aktivitas akan tetap dijeda.
Saat aktivitas beralih ke status Dijeda, komponen berbasis siklus proses yang terkait dengan siklus proses aktivitas akan menerima peristiwa ON_PAUSE
. Di sinilah komponen siklus proses dapat menghentikan fungsi apa pun yang tidak perlu dijalankan saat komponen tidak ada di latar depan, seperti menghentikan pratinjau kamera.
Gunakan metode onPause()
untuk menjeda atau menyesuaikan operasi yang tidak dapat dilanjutkan, atau mungkin dilanjutkan dalam moderasi, saat Activity
dalam status Dijeda, dan Anda berharap untuk segera dilanjutkan.
Anda juga dapat menggunakan metode onPause()
untuk
melepaskan resource sistem, menangani sensor (seperti GPS), atau resource apa pun yang
memengaruhi masa pakai baterai saat aktivitas Anda Dijeda dan pengguna tidak
memerlukannya.
Namun, seperti yang disebutkan di bagian tentang onResume()
, aktivitas yang Dijeda mungkin masih terlihat sepenuhnya jika aplikasi berada dalam mode multi-aplikasi.
Sebaiknya gunakan onStop()
, bukan onPause()
, untuk sepenuhnya merilis atau menyesuaikan
resource dan operasi terkait UI untuk mendukung mode multi-aplikasi dengan lebih baik.
Contoh LifecycleObserver
berikut yang bereaksi terhadap peristiwa ON_PAUSE
adalah pasangan dari contoh peristiwa ON_RESUME
sebelumnya, dengan merilis kamera yang melakukan inisialisasi setelah peristiwa ON_RESUME
diterima:
Kotlin
class CameraComponent : LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun releaseCamera() { camera?.release() camera = null } ... }
Java
public class JavaCameraComponent implements LifecycleObserver { ... @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void releaseCamera() { if (camera != null) { camera.release(); camera = null; } } ... }
Contoh ini menempatkan kode rilis kamera setelah
peristiwa ON_PAUSE
diterima oleh LifecycleObserver
.
Eksekusi onPause()
sangat singkat dan
belum tentu menawarkan cukup waktu untuk melakukan operasi penyimpanan. Karena alasan
ini, jangan gunakan onPause()
untuk menyimpan data aplikasi atau
pengguna, melakukan panggilan jaringan, atau menjalankan transaksi database. Pekerjaan tersebut mungkin tidak
selesai sebelum metode selesai.
Sebagai gantinya, lakukan operasi penonaktifan yang berat selama
onStop()
. Untuk mengetahui informasi selengkapnya
tentang operasi yang sesuai untuk dilakukan selama
onStop()
, lihat bagian berikutnya. Untuk mengetahui informasi selengkapnya tentang cara menyimpan
data, lihat bagian tentang menyimpan dan memulihkan status.
Penyelesaian metode onPause()
tidak berarti bahwa aktivitas meninggalkan status Dijeda. Sebaliknya, aktivitas
tetap dalam status ini sampai aktivitas dilanjutkan atau menjadi sama sekali
tidak terlihat oleh pengguna. Jika aktivitas berlanjut, sistem sekali lagi memanggil callback onResume()
.
Jika aktivitas kembali dari status Dijeda ke status Dilanjutkan, sistem akan menyimpan instance Activity
tetap ada di memori, dan memanggil kembali instance tersebut saat sistem memanggil onResume()
.
Dalam skenario ini, Anda tidak perlu menginisialisasi ulang komponen yang dibuat selama salah satu
metode callback yang mengarah ke status Dilanjutkan. Jika aktivitas menjadi
sama sekali tidak terlihat, sistem akan memanggil
onStop()
.
onStop()
Jika tidak lagi terlihat oleh pengguna, aktivitas Anda akan memasuki
status Berhenti, dan sistem memanggil
callback onStop()
. Ini dapat terjadi ketika aktivitas yang baru diluncurkan mencakup seluruh layar. Sistem
juga memanggil onStop()
saat aktivitas selesai berjalan dan akan dihentikan.
Saat aktivitas berpindah ke status Berhenti, komponen berbasis siklus proses yang terkait dengan siklus proses aktivitas akan menerima peristiwa ON_STOP
. Di sinilah komponen siklus proses dapat menghentikan fungsi apa pun yang tidak perlu dijalankan saat komponen tidak terlihat di layar.
Dalam metode onStop()
, rilis atau sesuaikan
resource yang tidak diperlukan saat aplikasi tidak terlihat oleh pengguna. Misalnya, aplikasi Anda dapat menjeda animasi atau beralih dari pembaruan lokasi yang sangat akurat ke kurang akurat. Menggunakan
onStop()
, bukan onPause()
,
berarti pekerjaan terkait UI akan berlanjut, meskipun pengguna melihat aktivitas Anda dalam mode
multi-aplikasi.
Selain itu, gunakan onStop()
untuk melakukan operasi penonaktifan yang relatif intensif CPU. Misalnya, jika tidak dapat menemukan waktu yang lebih baik untuk menyimpan informasi ke database, Anda dapat melakukannya selama onStop()
. Contoh berikut menunjukkan implementasi onStop()
yang menyimpan konten catatan draf ke penyimpanan persisten:
Kotlin
override fun onStop() { // Call the superclass method first. super.onStop() // Save the note's current draft, because the activity is stopping // and we want to be sure the current note progress isn't lost. val values = ContentValues().apply { put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()) put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()) } // Do this update in background on an AsyncQueryHandler or equivalent. asyncQueryHandler.startUpdate( token, // int token to correlate calls null, // cookie, not used here uri, // The URI for the note to update. values, // The map of column names and new values to apply to them. null, // No SELECT criteria are used. null // No WHERE columns are used. ) }
Java
@Override protected void onStop() { // Call the superclass method first. super.onStop(); // Save the note's current draft, because the activity is stopping // and we want to be sure the current note progress isn't lost. ContentValues values = new ContentValues(); values.put(NotePad.Notes.COLUMN_NAME_NOTE, getCurrentNoteText()); values.put(NotePad.Notes.COLUMN_NAME_TITLE, getCurrentNoteTitle()); // Do this update in background on an AsyncQueryHandler or equivalent. asyncQueryHandler.startUpdate ( mToken, // int token to correlate calls null, // cookie, not used here uri, // The URI for the note to update. values, // The map of column names and new values to apply to them. null, // No SELECT criteria are used. null // No WHERE columns are used. ); }
Contoh kode sebelumnya menggunakan SQLite secara langsung. Namun, sebaiknya gunakan Room, library persistensi yang menyediakan lapisan abstraksi atas SQLite. Untuk mempelajari lebih lanjut manfaat menggunakan Room dan cara mengimplementasikan Room di aplikasi Anda, lihat panduan Library Persistensi Room.
Saat aktivitas Anda memasuki status Berhenti, objek Activity
disimpan di memori: objek ini mempertahankan semua informasi status dan anggota, tetapi tidak dilampirkan ke pengelola jendela. Ketika dilanjutkan, aktivitas akan mengingat kembali informasi ini.
Anda tidak perlu
melakukan inisialisasi ulang komponen yang dibuat selama salah satu metode callback
yang mengarah ke status Dilanjutkan. Sistem juga melacak status
saat ini untuk setiap objek View
dalam tata letak, jadi jika
pengguna memasukkan teks ke dalam widget EditText
, konten
tersebut dipertahankan sehingga Anda tidak perlu menyimpan dan memulihkannya.
Catatan: Setelah aktivitas Anda dihentikan, sistem mungkin menghancurkan proses yang berisi aktivitas jika sistem perlu memulihkan memori.
Meskipun sistem menghancurkan proses saat aktivitas
dihentikan, sistem masih mempertahankan status objek View
, seperti teks dalam widget EditText
, dalam
Bundle
—blob pasangan nilai kunci—dan memulihkannya
jika pengguna menavigasi kembali ke aktivitas. Untuk
informasi selengkapnya tentang memulihkan aktivitas yang menjadi tujuan pengembalian pengguna, lihat
bagian tentang menyimpan dan memulihkan status.
Dari status Berhenti, aktivitas akan kembali untuk berinteraksi dengan pengguna, atau aktivitas akan selesai berjalan dan hilang. Jika aktivitas kembali, sistem akan memanggil onRestart()
.
Jika Activity
selesai berjalan, sistem akan memanggil onDestroy()
.
onDestroy()
onDestroy()
dipanggil sebelum aktivitas ditutup. Sistem memanggil callback ini karena salah satu dari dua alasan:
-
Aktivitas selesai, karena pengguna benar-benar menutup
aktivitas atau karena
finish()
dipanggil pada aktivitas. - Sistem sementara menutup aktivitas karena perubahan konfigurasi, seperti rotasi perangkat atau memasuki mode multi-aplikasi.
Saat aktivitas berpindah ke status dihancurkan, komponen berbasis siklus proses apa pun yang terkait
dengan siklus proses aktivitas akan menerima
peristiwa ON_DESTROY
. Di sinilah komponen siklus proses dapat membersihkan apa pun yang diperlukan sebelum Activity
dihancurkan.
Daripada menempatkan logika di Activity
untuk menentukan alasan halaman dihancurkan,
gunakan objek ViewModel
untuk memuat
data tampilan yang relevan untuk Activity
Anda. Jika Activity
dibuat ulang
karena perubahan konfigurasi, ViewModel
tidak perlu melakukan apa pun karena
hal tersebut dipertahankan dan diberikan ke instance Activity
berikutnya.
Jika Activity
tidak dibuat ulang, ViewModel
akan
memanggil metode onCleared()
yang dapat
membersihkan data yang diperlukan sebelum dihancurkan. Anda dapat membedakan kedua skenario ini dengan
metode isFinishing()
.
Jika aktivitas selesai, onDestroy()
adalah callback siklus proses terakhir yang
diterima aktivitas. Jika onDestroy()
dipanggil sebagai hasil dari perubahan
konfigurasi, sistem akan segera membuat instance aktivitas baru, lalu memanggil
onCreate()
pada instance baru tersebut dalam konfigurasi baru.
Callback onDestroy()
melepaskan semua resource yang tidak dirilis oleh callback
sebelumnya, seperti onStop()
.
Status aktivitas dan pengeluaran dari memori
Sistem mematikan proses ketika perlu membebaskan RAM. Kemungkinan sistem menghentikan proses tertentu bergantung pada status proses pada saat itu. Pada gilirannya, status proses bergantung pada status aktivitas yang berjalan dalam proses. Tabel 1 menunjukkan korelasi antara status proses, status aktivitas, dan kemungkinan sistem menghentikan proses. Tabel ini hanya berlaku jika proses tidak menjalankan jenis komponen aplikasi lainnya.
Kemungkinan ditutup | Status proses | Status aktivitas akhir |
---|---|---|
Terendah | Latar depan (memiliki atau akan mendapatkan fokus) | Dilanjutkan |
Rendah | Terlihat (tanpa fokus) | Dimulai/Dijeda |
Lebih tinggi | Latar belakang (tidak terlihat) | Dihentikan |
Tertinggi | Kosong | Ditutup |
Tabel 1. Hubungan antara siklus proses proses dan status aktivitas.
Sistem tidak pernah menutup aktivitas secara langsung untuk membebaskan memori. Sebaliknya, sistem ini akan menghentikan proses tempat aktivitas berjalan, bukan hanya menghancurkan aktivitas tetapi juga semua hal lain yang berjalan dalam proses. Untuk mempelajari cara mempertahankan dan memulihkan status UI aktivitas Anda saat terjadi penghentian proses yang dimulai oleh sistem, lihat bagian tentang menyimpan dan memulihkan status.
Pengguna juga dapat menghentikan proses menggunakan Pengelola Aplikasi, di bagian Setelan, untuk mematikan aplikasi yang sesuai.
Untuk mengetahui informasi selengkapnya tentang proses, lihat Ringkasan proses dan thread.
Menyimpan dan memulihkan status UI sementara
Pengguna berharap status UI aktivitas tetap sama selama perubahan konfigurasi, seperti rotasi atau beralih ke mode multi-aplikasi. Namun, sistem menutup aktivitas secara default ketika perubahan konfigurasi tersebut terjadi, sehingga menghapus semua status UI yang disimpan dalam instance aktivitas.
Demikian pula, pengguna mengharapkan status UI tetap sama jika beralih sementara dari aplikasi Anda ke aplikasi yang berbeda, lalu kembali ke aplikasi Anda nanti. Akan tetapi, sistem dapat menutup proses aplikasi saat pengguna pergi dan aktivitas Anda dihentikan.
Ketika batasan sistem menghancurkan aktivitas, pertahankan
status UI sementara pengguna menggunakan kombinasi
ViewModel
,
onSaveInstanceState()
,
dan/atau penyimpanan lokal. Untuk mempelajari lebih lanjut ekspektasi pengguna dibandingkan dengan perilaku
sistem dan cara terbaik mempertahankan data status UI yang kompleks di seluruh
aktivitas yang dimulai oleh sistem dan penghentian proses, lihat
Menyimpan status UI.
Bagian ini menguraikan status instance dan cara menerapkan metode
onSaveInstance()
, yang merupakan callback pada aktivitas itu sendiri. Jika data
UI Anda ringan, Anda dapat menggunakan onSaveInstance()
saja untuk mempertahankan status
UI baik saat terjadi perubahan konfigurasi maupun penghentian proses yang dimulai oleh sistem.
Namun, karena onSaveInstance()
menimbulkan biaya serialisasi/deserialisasi, pada
sebagian besar kasus, Anda menggunakan ViewModel
dan onSaveInstance()
, seperti
yang diuraikan dalam
Menyimpan status UI.
Catatan: Untuk mempelajari perubahan konfigurasi lebih lanjut, cara membatasi pembuatan ulang Aktivitas jika diperlukan, dan cara menanggapi perubahan konfigurasi tersebut dari sistem View dan Jetpack Compose, lihat halaman Menangani perubahan konfigurasi.
Status instance
Ada beberapa skenario ketika aktivitas Anda ditutup karena perilaku aplikasi normal, seperti ketika pengguna menekan tombol Kembali atau aktivitas Anda memberi sinyal penutupannya sendiri dengan memanggil metode finish()
.
Setelah aktivitas Anda dihancurkan karena pengguna menekan Kembali
atau aktivitas selesai dengan sendirinya, konsep sistem dan pengguna tentang
instance Activity
tersebut akan hilang selamanya. Dalam skenario
ini, ekspektasi pengguna sesuai dengan perilaku sistem, dan Anda tidak
perlu melakukan pekerjaan tambahan.
Namun, jika sistem menghancurkan aktivitas karena batasan sistem (seperti
perubahan konfigurasi atau tekanan memori), meskipun instance
Activity
yang sebenarnya hilang, sistem akan mengingat bahwa instance tersebut ada. Jika pengguna mencoba membuka kembali aktivitas, sistem membuat instance baru dari aktivitas tersebut menggunakan sekumpulan data yang disimpan yang menggambarkan status aktivitas saat ditutup.
Data tersimpan yang digunakan sistem untuk memulihkan
status sebelumnya disebut status instance. Kunci ini adalah kumpulan
key-value pair yang disimpan dalam objek Bundle
. Secara default, sistem menggunakan status instance Bundle
untuk menyimpan informasi
tentang setiap objek View
dalam tata letak aktivitas Anda, seperti
nilai teks yang dimasukkan ke dalam
widget EditText
.
Jadi, jika instance aktivitas Anda ditutup dan dibuat ulang, status tata letak akan dipulihkan seperti sebelumnya tanpa kode yang Anda perlukan. Akan tetapi, aktivitas Anda mungkin mempunyai lebih banyak informasi status yang ingin Anda pulihkan, seperti variabel anggota yang memantau progres pengguna dalam aktivitas tersebut.
Catatan: Agar sistem Android memulihkan status
tampilan dalam aktivitas Anda, setiap tampilan harus memiliki ID unik, yang disediakan oleh
atribut android:id
.
Objek Bundle
tidak sesuai untuk mempertahankan lebih dari
jumlah data yang sedikit, karena memerlukan serialisasi pada thread utama dan memakai
memori proses sistem. Untuk menyimpan lebih dari jumlah data yang sangat kecil,
lakukan pendekatan gabungan untuk mempertahankan data, menggunakan penyimpanan lokal
persisten, metode onSaveInstanceState()
, dan
class ViewModel
, seperti yang diuraikan dalam
Menyimpan status UI.
Menyimpan status UI yang sederhana dan ringan menggunakan onSaveInstanceState()
Ketika aktivitas Anda mulai berhenti, sistem akan memanggil metode onSaveInstanceState()
sehingga aktivitas Anda dapat menyimpan informasi status ke bundle status instance. Implementasi default metode ini menyimpan informasi sementara tentang status hierarki tampilan aktivitas, seperti teks dalam widget EditText
atau posisi scroll dari widget ListView
.
Untuk menyimpan informasi status instance tambahan untuk aktivitas Anda, ganti
onSaveInstanceState()
dan tambahkan key-value pair ke objek Bundle
yang disimpan
jika aktivitas Anda dihancurkan secara tidak terduga. Saat mengganti
onSaveInstanceState()
, Anda harus memanggil implementasi superclass
jika ingin implementasi default menyimpan status hierarki tampilan.
Hal ini ditunjukkan dalam contoh berikut:
Kotlin
override fun onSaveInstanceState(outState: Bundle?) { // Save the user's current game state. outState?.run { putInt(STATE_SCORE, currentScore) putInt(STATE_LEVEL, currentLevel) } // Always call the superclass so it can save the view hierarchy state. super.onSaveInstanceState(outState) } companion object { val STATE_SCORE = "playerScore" val STATE_LEVEL = "playerLevel" }
Java
static final String STATE_SCORE = "playerScore"; static final String STATE_LEVEL = "playerLevel"; // ... @Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state. savedInstanceState.putInt(STATE_SCORE, currentScore); savedInstanceState.putInt(STATE_LEVEL, currentLevel); // Always call the superclass so it can save the view hierarchy state. super.onSaveInstanceState(savedInstanceState); }
Catatan:
onSaveInstanceState()
tidak
dipanggil saat pengguna secara eksplisit menutup aktivitas atau dalam kasus lain ketika
finish()
dipanggil.
Untuk menyimpan data persisten, seperti preferensi pengguna atau data untuk database, ambil peluang yang sesuai saat aktivitas Anda berada di latar depan.
Jika tidak ada peluang seperti itu yang muncul, simpan data persisten selama metode onStop()
.
Memulihkan status UI aktivitas menggunakan status instance tersimpan
Saat aktivitas Anda dibuat kembali setelah sebelumnya ditutup, Anda dapat memulihkan status instance tersimpan dari Bundle
yang diteruskan sistem ke aktivitas Anda. Metode callback
onCreate()
dan
onRestoreInstanceState()
menerima Bundle
yang sama yang berisi
informasi status instance.
Karena metode onCreate()
akan dipanggil apakah sistem membuat instance baru dari aktivitas
atau membuat ulang yang sebelumnya, Anda perlu memeriksa apakah status Bundle
bernilai null sebelum mencoba membacanya. Jika statusnya null, sistem akan membuat instance baru dari aktivitas itu, bukan memulihkan instance sebelumnya yang ditutup.
Cuplikan kode berikut menunjukkan cara memulihkan beberapa
data status di onCreate()
:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Always call the superclass first // Check whether we're recreating a previously destroyed instance. if (savedInstanceState != null) { with(savedInstanceState) { // Restore value of members from saved state. currentScore = getInt(STATE_SCORE) currentLevel = getInt(STATE_LEVEL) } } else { // Probably initialize members with default values for a new instance. } // ... }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Always call the superclass first // Check whether we're recreating a previously destroyed instance. if (savedInstanceState != null) { // Restore value of members from saved state. currentScore = savedInstanceState.getInt(STATE_SCORE); currentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // Probably initialize members with default values for a new instance. } // ... }
Daripada memulihkan status selama
onCreate()
, Anda dapat memilih untuk mengimplementasikan
onRestoreInstanceState()
, yang dipanggil sistem setelah
metode onStart()
. Sistem memanggil
onRestoreInstanceState()
hanya jika ada status tersimpan untuk dipulihkan, sehingga Anda
tidak perlu memeriksa apakah Bundle
adalah null.
Kotlin
override fun onRestoreInstanceState(savedInstanceState: Bundle?) { // Always call the superclass so it can restore the view hierarchy. super.onRestoreInstanceState(savedInstanceState) // Restore state members from saved instance. savedInstanceState?.run { currentScore = getInt(STATE_SCORE) currentLevel = getInt(STATE_LEVEL) } }
Java
public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy. super.onRestoreInstanceState(savedInstanceState); // Restore state members from saved instance. currentScore = savedInstanceState.getInt(STATE_SCORE); currentLevel = savedInstanceState.getInt(STATE_LEVEL); }
Perhatian: Selalu panggil implementasi superclass
onRestoreInstanceState()
sehingga implementasi default dapat memulihkan status hierarki tampilan.
Melakukan navigasi antar-aktivitas
Aplikasi kemungkinan akan masuk dan keluar dari suatu aktivitas, mungkin berkali-kali, selama masa aktif aplikasi, seperti saat pengguna mengetuk tombol Kembali perangkat atau aktivitas meluncurkan aktivitas yang berbeda.
Bagian ini mencakup topik yang perlu Anda ketahui untuk mengimplementasikan transisi aktivitas yang berhasil. Topik-topik ini meliputi memulai aktivitas dari aktivitas lain, menyimpan status aktivitas, dan memulihkan status aktivitas.
Memulai satu aktivitas dari aktivitas lain
Aktivitas sering kali perlu memulai aktivitas lain di beberapa titik. Kebutuhan ini muncul, misalnya, ketika suatu aplikasi perlu berpindah dari layar saat ini ke layar baru.
Bergantung pada apakah aktivitas Anda menginginkan hasil kembali dari aktivitas baru
yang akan dimulai, Anda memulai aktivitas baru menggunakan metode
startActivity()
atau metode
startActivityForResult()
. Dalam kedua kasus tersebut, Anda memasukkan objek Intent
.
Objek Intent
menentukan aktivitas yang tepat
yang ingin Anda mulai atau menjelaskan jenis tindakan yang ingin Anda lakukan.
Sistem memilih aktivitas yang sesuai untuk Anda, yang bahkan bisa
berasal dari aplikasi berbeda. Objek Intent
juga dapat membawa sejumlah kecil data untuk digunakan oleh aktivitas yang dimulai.
Untuk informasi selengkapnya tentang class Intent
, lihat Intent dan Filter Intent.
startActivity()
Jika aktivitas yang baru dimulai tidak perlu menampilkan hasil, aktivitas saat ini dapat memulainya
dengan memanggil
metode
startActivity()
.
Saat menangani aplikasi Anda sendiri, biasanya Anda perlu meluncurkan aktivitas yang dikenal.
Misalnya, cuplikan kode berikut ini menunjukkan cara meluncurkan aktivitas yang disebut SignInActivity
.
Kotlin
val intent = Intent(this, SignInActivity::class.java) startActivity(intent)
Java
Intent intent = new Intent(this, SignInActivity.class); startActivity(intent);
Aplikasi Anda mungkin juga ingin melakukan beberapa tindakan, seperti mengirim email, pesan teks, atau pembaruan status, menggunakan data dari aktivitas Anda. Dalam hal ini, aplikasi Anda mungkin tidak memiliki aktivitasnya sendiri untuk melakukan tindakan tersebut, sehingga Anda dapat memanfaatkan aktivitas yang disediakan aplikasi lain pada perangkat, yang dapat melakukan tindakan itu untuk Anda.
Di sinilah intent sangat berharga. Anda dapat membuat intent yang menjelaskan tindakan yang ingin dilakukan, dan sistem akan meluncurkan aktivitas yang sesuai dari aplikasi lain. Jika ada beberapa aktivitas yang dapat menangani intent itu, pengguna dapat memilih aktivitas yang akan digunakan. Misalnya, jika ingin mengizinkan pengguna mengirim pesan email, Anda dapat membuat intent berikut:
Kotlin
val intent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_EMAIL, recipientArray) } startActivity(intent)
Java
Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra(Intent.EXTRA_EMAIL, recipientArray); startActivity(intent);
Tambahan EXTRA_EMAIL
yang ditambahkan ke intent adalah array string alamat email yang akan dikirimi email. Saat aplikasi email
merespons intent ini, aplikasi akan membaca array string yang disediakan dalam tambahan dan
menempatkan alamatnya di kolom "to" pada formulir penulisan email. Dalam situasi
ini, aktivitas aplikasi email dimulai, dan jika pengguna selesai,
aktivitas Anda akan dilanjutkan.
startActivityForResult()
Terkadang Anda ingin mendapatkan hasil kembali dari suatu aktivitas saat itu berakhir. Misalnya, Anda dapat memulai
aktivitas yang memungkinkan pengguna memilih seseorang dalam daftar kontak. Saat selesai, kueri akan menampilkan
orang yang dipilih. Untuk melakukan ini, Anda memanggil metode startActivityForResult(Intent, int)
, tempat parameter bilangan bulat mengidentifikasi panggilan.
ID ini dimaksudkan untuk membedakan beberapa panggilan ke
startActivityForResult(Intent, int)
dari aktivitas yang sama. Ini bukan ID global
dan tidak berisiko bertentangan dengan aplikasi atau aktivitas lainnya. Hasilnya akan kembali melalui metode onActivityResult(int, int, Intent)
Anda.
Saat keluar, aktivitas turunan dapat memanggil setResult(int)
untuk mengembalikan data ke induknya.
Aktivitas turunan harus menyediakan kode hasil, yang dapat berupa hasil standar
RESULT_CANCELED
, RESULT_OK
, atau nilai kustom apa pun
yang dimulai dari RESULT_FIRST_USER
.
Selain itu, aktivitas turunan dapat secara opsional menampilkan objek Intent
yang berisi data tambahan yang diinginkan. Aktivitas induk menggunakan
metode onActivityResult(int, int, Intent)
, beserta ID bilangan bulat aktivitas induk yang
disediakan, untuk menerima informasi.
Jika aktivitas turunan gagal karena alasan apa pun, seperti error, aktivitas induk
akan menerima hasil dengan kode RESULT_CANCELED
.
Kotlin
class MyActivity : Activity() { // ... override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // When the user center presses, let them pick a contact. startActivityForResult( Intent(Intent.ACTION_PICK,Uri.parse("content://contacts")), PICK_CONTACT_REQUEST) return true } return false } override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) { when (requestCode) { PICK_CONTACT_REQUEST -> if (resultCode == RESULT_OK) { // A contact was picked. Display it to the user. startActivity(Intent(Intent.ACTION_VIEW, intent?.data)) } } } companion object { internal val PICK_CONTACT_REQUEST = 0 } }
Java
public class MyActivity extends Activity { // ... static final int PICK_CONTACT_REQUEST = 0; public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { // When the user center presses, let them pick a contact. startActivityForResult( new Intent(Intent.ACTION_PICK, new Uri("content://contacts")), PICK_CONTACT_REQUEST); return true; } return false; } protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICK_CONTACT_REQUEST) { if (resultCode == RESULT_OK) { // A contact was picked. Display it to the user. startActivity(new Intent(Intent.ACTION_VIEW, data)); } } } }
Mengoordinasikan aktivitas
Bila suatu aktivitas memulai aktivitas lain, keduanya akan mengalami transisi siklus proses. Aktivitas pertama berhenti beroperasi dan memasuki status Dijeda atau Berhenti, sedangkan aktivitas lainnya dibuat. Jika aktivitas ini membagikan data yang disimpan ke disk atau tempat lain, penting untuk dipahami bahwa aktivitas pertama tidak sepenuhnya dihentikan sebelum yang kedua dibuat. Sebaliknya, proses memulai yang kedua tumpang tindih dengan proses penghentian yang pertama.
Urutan callback siklus proses ditentukan dengan baik, terutama ketika kedua aktivitas berada dalam proses yang sama—dengan kata lain, aplikasi yang sama—dan salah satunya memulai aktivitas yang lain. Berikut urutan operasi yang terjadi setelah Aktivitas A memulai Aktivitas B:
- Metode
onPause()
aktivitas A akan dieksekusi. - Metode
onCreate()
,onStart()
, danonResume()
aktivitas B dieksekusi secara berurutan. Aktivitas B sekarang mendapatkan fokus pengguna. - Jika Aktivitas A tidak lagi terlihat di layar, metode
onStop()
-nya akan dijalankan.
Urutan callback siklus proses ini memungkinkan Anda mengelola transisi informasi dari satu aktivitas ke aktivitas lainnya.