Siklus proses aktivitas

Saat pengguna menelusuri, keluar, dan kembali ke aplikasi Anda, instance Activity dalam aplikasi Anda melakukan transisi ke berbagai status dalam siklus prosesnya. Class Activity memberikan sejumlah callback yang memberi tahu aktivitas saat status berubah atau bahwa sedang membuat, menghentikan, atau melanjutkan aktivitas atau menghancurkan 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 Anda membuat pemutar streaming video, Anda dapat menjeda video dan menghentikan koneksi jaringan saat pengguna beralih ke aplikasi lain. Saat pengguna kembali, Anda dapat menyambung kembali ke jaringan dan membiarkan pengguna melanjutkan video dari tempat yang sama.

Setiap callback memungkinkan Anda melakukan tugas tertentu yang sesuai untuk 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, penerapan callback siklus proses yang baik dapat membantu aplikasi Anda hindari 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, menjelaskan setiap callback: apa yang terjadi secara internal saat mereka mengeksekusi dan apa yang perlu Anda implementasikan selama wawancara.

Selanjutnya, dokumen tersebut secara singkat memperkenalkan hubungan antara status aktivitas dan kerentanan suatu proses akan ditutup oleh sistem. Akhirnya, ini membahas beberapa topik yang terkait dengan transisi antara status aktivitas.

Untuk informasi tentang cara menangani 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 dalam dengan komponen arsitektur, lihat Panduan untuk arsitektur aplikasi.

Konsep siklus proses aktivitas

Untuk menavigasi transisi antartahapan siklus proses aktivitas, Class Activity menyediakan kumpulan inti enam callback: onCreate(), onStart(), onResume(), onPause(), onStop(), dan onDestroy(). Sistem memanggil setiap callback saat aktivitas memasuki status baru.

Gambar 1 menyajikan representasi visual dari paradigma ini.

Gambar 1. Ilustrasi sederhana dari siklus proses aktivitas.

Setelah pengguna mulai meninggalkan aktivitas, sistem memanggil metode untuk membongkar aktivitas. Dalam beberapa kasus, aktivitas hanya sebagian dibongkar dan masih berada dalam memori, seperti ketika pengguna beralih aplikasi lain. Dalam kasus ini, aktivitas masih dapat kembali ke latar depan.

Jika pengguna kembali ke aktivitas, melanjutkan dari bagian terakhir yang ditinggalkan pengguna. Dengan beberapa pengecualian, aplikasi dibatasi dari memulai aktivitas saat berjalan di latar belakang.

Kemungkinan sistem mematikan proses tertentu, bersama dengan aktivitas di dalamnya, tergantung pada status aktivitas pada saat itu. Untuk informasi selengkapnya tentang hubungan antara kerentanan terhadap pengecualian, lihat bagian tentang status aktivitas dan pengeluaran dari memori.

Bergantung pada kompleksitas aktivitas, Anda mungkin tidak perlu mengimplementasikan semua metode siklus proses. Namun, penting bagi Anda memahami setiap variabel tersebut dan mengimplementasikannya yang membuat aplikasi Anda berperilaku dengan cara 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, kode tempat yang mengimplementasikan tindakan komponen dependen dalam metode komponen aplikasi, bukan metode siklus proses aktivitas. Untuk mencapai hal ini, Anda perlu untuk 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. Di onCreate() menjalankan logika startup aplikasi dasar hanya terjadi satu kali sepanjang siklus aktivitas.

Misalnya, implementasi onCreate() dapat mengikat data ke daftar, mengaitkan aktivitas dengan ViewModel, dan membuat instance beberapa variabel cakupan class. Metode ini menerima parameter savedInstanceState, yang merupakan Bundle objek yang berisi status aktivitas yang sebelumnya disimpan. Jika aktivitas memiliki belum pernah ada sebelumnya, nilai objek Bundle adalah null.

Jika Anda memiliki komponen berbasis siklus hidup yang terhubung dengan siklus hidup aktivitas Anda, sistem akan menerima ON_CREATE peristiwa. Metode yang dianotasi dengan @OnLifecycleEvent dipanggil agar berbasis siklus proses Anda dapat menjalankan kode pengaturan apa pun yang diperlukan untuk status yang dibuat.

Contoh metode onCreate() berikut menunjukkan penyiapan dasar untuk aktivitas, 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 menjadi 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 dapat membuat objek View baru dalam kode aktivitas Anda dan membangun hierarki tampilan dengan menyisipkan objek View baru ke ViewGroup. Anda kemudian menggunakan tata letak tersebut dengan meneruskan root ViewGroup dengan setContentView(). Untuk informasi selengkapnya tentang membuat antarmuka pengguna, lihat dokumentasi antarmuka pengguna.

Aktivitas Anda tidak tetap berada di opsi Dibuat status. Setelah metode onCreate() menyelesaikan eksekusi, aktivitas akan memasuki mode Started dan sistem akan memanggil onStart() dan onResume() secara cepat suksesi.

onStart()

Ketika aktivitas memasuki status Dimulai, sistem memanggil onStart(). Panggilan ini membuat aktivitas terlihat oleh pengguna sebagai aplikasi mempersiapkan aktivitas untuk masuk ke latar depan dan menjadi interaktif. Misalnya, metode ini adalah di mana kode yang mempertahankan UI diinisialisasi.

Saat aktivitas berpindah ke status Dimulai, komponen berbasis siklus proses apa pun yang terikat ke siklus hidup aktivitas menerima Peristiwa ON_START.

Metode onStart() selesai dengan cepat dan, seperti dengan status Dibuat, aktivitas tidak tetap dalam status Started. Setelah callback ini selesai, aktivitas akan memasuki Dilanjutkan dan sistem akan memanggil metode Metode onResume().

onResume()

Ketika aktivitas memasuki status Dilanjutkan, aktivitas akan muncul di latar depan, dan sistem memanggil onResume() . Ini adalah status saat aplikasi berinteraksi dengan pengguna. Aplikasi tetap dalam status ini sampai terjadi sesuatu pada mengalihkan fokus dari aplikasi, misalnya perangkat yang menerima panggilan telepon, menavigasi ke aktivitas lain, atau layar perangkat mati.

Saat aktivitas berpindah ke status Dilanjutkan, komponen berbasis siklus proses akan terikat ke siklus hidup aktivitas menerima ON_RESUME peristiwa. 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 peristiwa interupsi terjadi, aktivitas akan memasuki status Dijeda dan sistem memanggil Callback onPause().

Jika aktivitas kembali ke status Dilanjutkan dari status Dijeda, sistem sekali lagi memanggil Metode onResume(). Karena alasan ini, terapkan onResume() untuk melakukan inisialisasi komponen yang Anda rilis selama onPause() dan untuk melakukan inisialisasi yang harus terjadi setiap kali aktivitas memasuki tab Dilanjutkan status.

Berikut ini contoh komponen berbasis siklus proses yang mengakses kamera saat komponen akan 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 terlihat sepenuhnya bahkan saat dalam status Dijeda. Misalnya, ketika aplikasi berada dalam mode multi-aplikasi dan pengguna mengetuk jendela yang tidak berisi aktivitas Anda, aktivitas Anda berpindah ke status Dijeda.

Jika Anda ingin kamera hanya aktif saat aplikasi Dilanjutkan (terlihat dan aktif di latar depan), lalu melakukan inisialisasi kamera setelah ON_RESUME peristiwa yang Anda tunjukkan sebelumnya. Jika Anda ingin kamera tetap aktif saat beraktivitas Dijeda tetapi terlihat, misalnya dalam mode multi-aplikasi, kemudian melakukan inisialisasi kamera setelah peristiwa ON_START.

Namun, memiliki kamera aktif saat aktivitas Dijeda dapat menolak akses ke kamera ke kamera lain Aplikasi dilanjutkan dalam mode multi-aplikasi. Terkadang perlu untuk menjaga kamera aktif saat aktivitas Dijeda, tetapi bisa menurunkan pengalaman pengguna secara keseluruhan jika Anda melakukannya.

Oleh karena itu, pikirkan baik-baik tentang letak paling tepat untuk mengendalikan sumber daya sistem bersama dalam konteks mode multi-aplikasi. Untuk mempelajari lebih lanjut cara mendukung multi-aplikasi Anda, 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 melakukan inisialisasi setelah peristiwa ON_START, lepaskan atau hentikan setelah Peristiwa ON_STOP. Jika Anda melakukan inisialisasi setelah peristiwa ON_RESUME, rilis setelah Peristiwa ON_PAUSE.

Cuplikan kode sebelumnya menempatkan kode inisialisasi kamera dalam berbasis siklus proses. Anda dapat menempatkan kode ini langsung ke dalam aktivitas callback siklus proses, seperti onStart() dan onStop(), tetapi kami tidak merekomendasikannya. Menambahkan logika ini menjadi komponen independen yang berbasis siklus proses memungkinkan Anda menggunakan kembali komponen tersebut 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 akan keluar aktivitas Anda, meskipun tidak selalu berarti aktivitas sedang dihancurkan. Ini menunjukkan bahwa aktivitas tidak lagi di latar depan, tetapi tetap terlihat jika pengguna berada dalam mode multi-aplikasi. Ada beberapa alasan mengapa suatu aktivitas masuk negara bagian ini:

  • Peristiwa yang mengganggu eksekusi aplikasi, seperti yang dijelaskan di bagian tentang callback onResume(), menjeda aktivitas saat ini. Ini adalah kasus yang paling umum.
  • Dalam mode multi-aplikasi, hanya satu aplikasi yang memiliki fokus kapan saja, dan sistem akan menjeda semua aplikasi lain.
  • Pembukaan aktivitas semi-transparan baru, seperti dialog, menjeda aktivitas yang dicakup. Selama aktivitas terlihat sebagian tetapi tidak dalam fokus, tetap dijeda.

Saat aktivitas berpindah ke status Dijeda, komponen berbasis siklus proses apa pun yang terikat ke siklus hidup aktivitas 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 berlanjut dalam moderasi, saat Activity dalam status Dijeda, dan Anda kami akan segera melanjutkannya.

Anda juga dapat menggunakan metode onPause() untuk melepaskan sumber daya sistem, menangani sensor (seperti GPS), atau sumber daya apa pun yang memengaruhi masa pakai baterai saat aktivitas Anda Dijeda dan pengguna tidak membutuhkannya.

Namun, seperti yang disebutkan di bagian tentang onResume(), mungkin tetap terlihat sepenuhnya jika aplikasi berada dalam mode multi-aplikasi. Sebaiknya gunakan onStop(), bukan onPause(), untuk melepaskan atau menyesuaikan sepenuhnya Resource dan operasi terkait UI untuk lebih mendukung mode multi-aplikasi.

Contoh LifecycleObserver berikut bereaksi terhadap peristiwa ON_PAUSE adalah kebalikan dari yang sebelumnya Contoh peristiwa ON_RESUME, 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 tidak selalu menawarkan waktu yang cukup untuk melakukan operasi penyimpanan. Untuk ini alasan, jangan gunakan onPause() untuk menyimpan aplikasi atau pengguna data, melakukan panggilan jaringan, atau menjalankan transaksi {i>database<i}. Pekerjaan tersebut mungkin tidak sebelum metode selesai.

Sebagai gantinya, lakukan operasi penonaktifan beban berat selama onStop(). Untuk informasi lebih lanjut tentang operasi yang sesuai untuk dilakukan selama onStop(), lihat bagian berikutnya. Untuk informasi selengkapnya tentang menyimpan data, lihat bagian tentang menyimpan dan memulihkan status.

Penyelesaian metode onPause() tidak berarti bahwa aktivitas meninggalkan status Dijeda. Melainkan, aktivitas tetap dalam status ini sampai aktivitas dilanjutkan atau menjadi sepenuhnya tidak terlihat oleh pengguna. Jika aktivitas berlanjut, sistem sekali lagi memanggil callback onResume().

Jika kembali dari status Dijeda ke status Dilanjutkan, sistem menyimpan instance Activity yang ada di memori, penarikan pada instance tersebut saat sistem memanggil onResume(). Dalam skenario ini, Anda tidak perlu menginisialisasi ulang komponen yang dibuat selama metode callback yang mengarah ke status Dilanjutkan. Jika aktivitas tersebut menjadi sama sekali tidak terlihat, sistem akan memanggil onStop().

onStop()

Jika aktivitas Anda tidak lagi terlihat oleh pengguna, aktivitas akan memasuki Dihentikan, dan sistem memanggil Callback onStop(). Hal ini dapat terjadi saat aktivitas yang baru diluncurkan mencakup seluruh layar. Tujuan sistem juga memanggil onStop() ketika aktivitas selesai berjalan dan akan segera dihentikan.

Saat aktivitas berpindah ke status Berhenti, komponen berbasis siklus proses akan terikat ke siklus hidup aktivitas 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(), lepaskan 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 bahwa pekerjaan terkait UI berlanjut, bahkan saat pengguna melihat aktivitas Anda dalam multi-aplikasi mode.

Selain itu, gunakan onStop() untuk melakukan operasi shutdown yang relatif intensif CPU. Misalnya, jika Anda tidak dapat menemukan waktu yang lebih baik untuk menyimpan informasi ke {i>database<i}, 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 selengkapnya tentang manfaat menggunakan Room dan cara menerapkan Room di aplikasi Anda, lihat Library Persistensi Room kami.

Ketika aktivitas Anda memasuki status Berhenti, Activity objek disimpan di memori: objek ini mempertahankan semua status dan anggota informasi, tetapi tidak dilampirkan ke pengelola jendela. Kapan aktivitas resume, sistem akan mengingat informasi ini.

Anda tidak perlu menginisialisasi ulang komponen yang dibuat dalam salah satu metode callback yang mengarah ke status Dilanjutkan. Sistem juga melacak arus untuk setiap objek View dalam tata letak, jadi jika pengguna memasukkan teks ke dalam widget EditText, yang tetapi konten tetap 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. Bahkan jika sistem menghancurkan proses saat aktivitas dihentikan, sistem masih mempertahankan status View objek, seperti teks dalam widget EditText, dalam Bundle—blob pasangan nilai kunci—dan memulihkannya jika pengguna kembali ke aktivitas. Sebagai informasi selengkapnya tentang memulihkan aktivitas tempat pengguna kembali, lihat 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:

  1. Aktivitas selesai, karena pengguna sepenuhnya menolak aktivitas atau karena finish() sedang pada aktivitas.
  2. Sistem menghancurkan aktivitas untuk sementara karena konfigurasi perubahan, seperti rotasi perangkat atau memasuki mode multi-aplikasi.

Saat aktivitas berpindah ke status dihancurkan, komponen berbasis siklus proses apa pun yang terikat ke siklus hidup aktivitas menerima Peristiwa ON_DESTROY. Di sinilah komponen siklus hidup dapat membersihkan apa pun yang mereka butuhkan sebelum Activity dihancurkan.

Alih-alih menempatkan logika di Activity Anda untuk menentukan alasan perusakannya, gunakan objek ViewModel untuk menampung data penayangan yang relevan untuk Activity Anda. Jika Activity dibuat ulang karena perubahan konfigurasi, ViewModel tidak perlu melakukan apa pun, karena data tersebut dipertahankan dan diberikan ke instance Activity berikutnya.

Jika Activity tidak dibuat ulang, ViewModel memiliki elemen Metode onCleared() dipanggil, dengan ia dapat membersihkan data apa pun yang diperlukan sebelum dihancurkan. Anda dapat membedakan antara kedua skenario ini dengan Metode isFinishing().

Jika aktivitas selesai, onDestroy() adalah callback siklus proses akhir yang yang diterima aktivitas. Jika onDestroy() dipanggil sebagai hasil konfigurasi perubahan, sistem segera membuat instance aktivitas baru dan kemudian memanggil onCreate() pada instance baru di konfigurasi baru.

Callback onDestroy() melepaskan semua resource yang tidak dirilis sebelumnya callback, seperti onStop().

Status aktivitas dan pengeluaran dari memori

Sistem mengakhiri proses ketika perlu mengosongkan RAM. Kemungkinan sistem mematikan proses tertentu tergantung pada keadaan proses pada saat itu. Pada gilirannya, status proses bergantung pada status aktivitas yang berjalan dalam proses. Tabel 1 menunjukkan korelasi antara status proses dan aktivitas status, dan kemungkinan sistem menghentikan proses. Tabel ini hanya berlaku jika proses tidak menjalankan jenis komponen aplikasi.

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, hal itu mematikan proses tempat aktivitas berjalan, tidak hanya menghancurkan aktivitas tetapi semua hal lain juga berjalan dalam proses. Untuk mempelajari cara mempertahankan dan memulihkan status UI aktivitas Anda saat proses penghentian yang dimulai oleh sistem terjadi, lihat bagian tentang menyimpan dan memulihkan status.

Pengguna juga dapat mematikan proses dengan menggunakan Pengelola Aplikasi, di bawah {i>Settings<i}, untuk menghentikan aplikasi yang sesuai.

Untuk informasi selengkapnya tentang proses, lihat Proses dan thread ringkasan.

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 menghancurkan proses aplikasi Anda saat pengguna sedang pergi dan aktivitas Anda dihentikan.

Jika batasan sistem menghancurkan aktivitas, pertahankan status UI sementara pengguna menggunakan kombinasi ViewModel, onSaveInstanceState(), dan/atau penyimpanan lokal. Untuk mempelajari lebih lanjut tentang ekspektasi pengguna dibandingkan dengan sistem dan cara terbaik untuk 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 mengimplementasikannya Metode onSaveInstance(), yang merupakan callback pada aktivitas itu sendiri. Jika Data UI bersifat ringan, Anda dapat menggunakan onSaveInstance() saja untuk mempertahankan UI status di perubahan konfigurasi dan penghentian proses yang dimulai oleh sistem. Namun, karena onSaveInstance() menimbulkan biaya serialisasi/deserialisasi, di biasanya Anda menggunakan ViewModel dan onSaveInstance(), sebagai diuraikan dalam Menyimpan status UI.

Catatan: Untuk mempelajari lebih lanjut perubahan konfigurasi, cara membatasi Aktivitas pembuatan ulang 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().

Saat aktivitas Anda dihancurkan karena pengguna menekan tombol Kembali atau aktivitas selesai dengan sendirinya, baik konsep sistem maupun konsep pengguna tentang instance Activity tersebut hilang selamanya. Di skenario, harapan pengguna cocok dengan perilaku sistem, dan Anda tidak memiliki pekerjaan tambahan yang harus dilakukan.

Namun, jika sistem menghancurkan aktivitas karena batasan sistem (seperti perubahan konfigurasi atau tekanan memori), maka meskipun Activity 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. Ini adalah kumpulan dari 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: Supaya 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 data dalam jumlah sangat kecil, karena memerlukan serialisasi pada thread utama memori proses-sistem. Untuk mempertahankan data dalam jumlah yang sangat kecil, mengambil pendekatan gabungan untuk menyimpan data, dengan menggunakan penyimpanan, metode onSaveInstanceState(), dan 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 menambahkan key-value pair ke objek Bundle yang disimpan jika aktivitas Anda dihancurkan secara tidak terduga. Saat Anda mengganti onSaveInstanceState(), Anda perlu memanggil implementasi superclass jika Anda 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 ketika pengguna secara eksplisit menutup aktivitas atau dalam kasus lain ketika finish() dipanggil.

Untuk menyimpan data persisten, seperti preferensi pengguna atau data untuk database, mengambil peluang yang sesuai saat aktivitas Anda berada di latar depan. Jika tidak ada peluang seperti itu, 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. Baik onCreate() dan onRestoreInstanceState() metode callback akan menerima Bundle yang sama yang berisi informasi status instance.

Karena metode onCreate() yang dipanggil apakah sistem membuat instance baru dari aktivitas Anda atau membuat ulang yang sebelumnya, Anda perlu memeriksa apakah status Bundle adalah {i>null<i} sebelum Anda mencoba untuk 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.
    }
    // ...
}

Alih-alih memulihkan status selama onCreate(), Anda dapat memilih untuk menerapkan onRestoreInstanceState(), yang dipanggil sistem setelah Metode onStart(). Sistem memanggil onRestoreInstanceState() jika ada status tersimpan untuk dipulihkan. Jadi, Anda perlu tidak perlu memeriksa apakah Bundle bernilai 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 bisa memulihkan status hierarki tampilan.

Melakukan navigasi antar aktivitas

Aplikasi cenderung masuk dan keluar dari suatu aktivitas, mungkin berkali-kali, selama masa pakai aplikasi, seperti saat pengguna mengetuk tombol Kembali di 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 atau tidak segera dimulai, Anda memulai aktivitas baru menggunakan startActivity() metode atau startActivityForResult() . Dalam kedua kasus tersebut, Anda memasukkan objek Intent.

Objek Intent menentukan aktivitas yang ingin dimulai atau menjelaskan jenis tindakan yang ingin dilakukan. Sistem memilih aktivitas yang sesuai untuk Anda, yang bahkan bisa dari aplikasi lain. 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 yang menjelaskan tindakan yang ingin Anda lakukan, dan sistem akan meluncurkan aktivitas dari aplikasi lain. Jika ada beberapa aktivitas yang dapat menangani intent itu, pengguna dapat memilih aktivitas yang akan digunakan. Misalnya, jika Anda ingin membiarkan pengguna mengirim sebuah 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 dari alamat email yang akan dikirimi email. Saat aplikasi email merespons intent ini, maka akan membaca array string yang disediakan dalam ekstra dan menempatkan alamat dalam kolom "{i>to<i}" pada formulir penulisan email. Di sini ini, aktivitas aplikasi email akan dimulai, dan ketika pengguna selesai, aktivitas Anda dilanjutkan.

startActivityForResult()

Terkadang Anda ingin mendapatkan hasil kembali dari suatu aktivitas saat itu berakhir. Misalnya, Anda bisa memulai aktivitas yang memungkinkan pengguna memilih orang dalam daftar kontak. Setelah berakhir, fungsi ini akan orang yang dipilih. Untuk melakukan ini, Anda memanggil metode startActivityForResult(Intent, int), tempat parameter bilangan bulat mengidentifikasi panggilan.

ID ini dimaksudkan untuk membedakan antara beberapa panggilan untuk startActivityForResult(Intent, int) dari aktivitas yang sama. Bukan ID global dan tidak berisiko bertentangan dengan aplikasi atau aktivitas lain. Hasilnya kembali melalui onActivityResult(int, int, Intent) .

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 mulai dari RESULT_FIRST_USER.

Selain itu, aktivitas turunan dapat secara opsional menampilkan Intent yang berisi data tambahan yang diinginkan. Aktivitas induk menggunakan onActivityResult(int, int, Intent) , bersama dengan ID bilangan bulat aktivitas induk awalnya yang disediakan, untuk menerima informasi.

Jika aktivitas turunan gagal karena suatu alasan, 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 sudah didefinisikan dengan baik, terutama bila kedua aktivitas tersebut dalam proses yang sama—dengan kata lain, aplikasi yang sama—dan satu aplikasi memulai yang lainnya. Berikut urutan operasi yang terjadi setelah Aktivitas A memulai Aktivitas B:

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

Urutan callback siklus proses ini memungkinkan Anda mengelola transisi informasi dari satu aktivitas ke aktivitas lainnya.