Level siklus proses aktivitas

Pengantar

Dalam codelab ini, Anda akan mempelajari lebih lanjut bagian dasar Android: aktivitas. Siklus proses aktivitas adalah kumpulan status aktivitas yang terjadi selama siklus prosesnya. Siklus proses dimulai dari saat aktivitas pertama kali dibuat hingga saat dimusnahkan dan sistem mengklaim kembali resource aktivitas tersebut. Saat pengguna membuka beberapa aktivitas di aplikasi Anda (serta ke dalam dan ke luar aplikasi), aktivitas tersebut akan bertransisi antar-status yang berbeda dalam siklus proses aktivitas.

Sebagai developer Android, Anda perlu memahami siklus proses aktivitas. Jika aktivitas Anda tidak merespons perubahan status siklus proses dengan benar, aplikasi Anda dapat menghasilkan bug aneh, perilaku yang membingungkan bagi pengguna, atau menggunakan terlalu banyak resource sistem Android. Memahami siklus proses Android dan merespons perubahan keadaan siklus proses dengan benar, sangat penting agar dapat menjadi developer Android yang baik.

Yang harus sudah Anda ketahui

  • Pengertian aktivitas, dan cara membuatnya di aplikasi Anda.
  • Fungsi dari metode onCreate() aktivitas dan jenis operasi yang dijalankan dalam metode tersebut.

Yang akan Anda pelajari

  • Cara mencetak informasi logging ke Logcat.
  • Dasar-dasar siklus proses Activity, dan callback yang dipanggil saat aktivitas berpindah antar-status.
  • Cara mengganti metode callback siklus proses untuk menjalankan operasi pada waktu yang berbeda di dalam siklus proses aktivitas.

Yang akan Anda lakukan

  • Memodifikasi aplikasi starter bernama DesserbaClicker untuk menambahkan informasi logging yang ditampilkan di Logcat.
  • Mengganti metode callback siklus proses dan perubahan log pada status aktivitas.
  • Menjalankan aplikasi dan mencatat informasi logging yang muncul saat aktivitas dimulai, dihentikan, dan dilanjutkan.
  • Menerapkan metode onSaveInstanceState() untuk mempertahankan data aplikasi yang mungkin hilang jika konfigurasi perangkat berubah. Menambahkan kode untuk memulihkan data tersebut saat aplikasi dimulai lagi.

Dalam codelab ini, Anda akan menggunakan aplikasi starter yang disebut DessertClicker. Di aplikasi ini, setiap kali pengguna mengetuk hidangan penutup (dessert) di layar, aplikasi akan "membeli" makanan penutup untuk pengguna. Aplikasi memperbarui nilai dalam tata letak untuk jumlah makanan penutup yang dibeli, dan juga untuk jumlah total yang dibelanjakan pengguna.

8216c20f5571fc04.png

Aplikasi ini berisi beberapa bug yang terkait dengan siklus proses Android: Misalnya, dalam keadaan tertentu, aplikasi menyetel ulang nilai makanan penutup ke angka 0. Memahami siklus proses Android akan membantu Anda memahami penyebab terjadinya masalah ini, serta cara memperbaikinya.

Mendapatkan aplikasi awal

Download kode awal DessertClicker. dan buka di Android Studio.

Jika Anda menggunakan kode awal dari GitHub, pastikan nama foldernya adalah android-basics-kotlin-dessert-clicker-app-starter. Pilih folder ini saat Anda membuka project di Android Studio.

Untuk mendapatkan kode codelab ini dan membukanya di Android Studio, lakukan hal berikut.

Mendapatkan kode

  1. Klik URL yang diberikan. Tindakan ini akan membuka halaman GitHub project di browser.
  2. Di halaman GitHub project, klik tombol Code yang akan menampilkan dialog.

Eme2bJP46u-pMpnXVfm-bS2N2dlyq6c0jn1DtQYqBaml7TUhzXDWpYoDI0lGKi4xndE_uJw8sKfwfOZ1fC503xCVZrbh10JKJ4iEHdLDwFfdvnOheNxkokITW1LW6UZTncVJJUZ5Fw

  1. Di dialog, klik tombol Download ZIP untuk menyimpan project di komputer. Tunggu download selesai.
  2. Temukan file di komputer Anda (mungkin di folder Downloads).
  3. Klik dua kali pada file ZIP untuk mengekstraknya. Tindakan ini akan membuat folder baru yang berisi file project.

Membuka project di Android Studio

  1. Mulai Android Studio.
  2. Di jendela Welcome to Android Studio, klik Open an existing Android Studio project.

Tdjf5eS2nCikM9KdHgFaZNSbIUCzKXP6WfEaKVE2Oz1XIGZhgTJYlaNtXTHPFU1xC9pPiaD-XOPdIxVxwZAK8onA7eJyCXz2Km24B_8rpEVI_Po5qlcMNN8s4Tkt6kHEXdLQTDW7mg

Catatan: Jika Android Studio sudah terbuka, pilih opsi menu File > New > Import Project.

PaMkVnfCxQqSNB1LxPpC6C6cuVCAc8jWNZCqy5tDVA6IO3NE2fqrfJ6p6ggGpk7jd27ybXaWU7rGNOFi6CvtMyHtWdhNzdAHmndzvEdwshF_SG24Le01z7925JsFa47qa-Q19t3RxQ

  1. Di dialog Import Project, buka lokasi folder project yang telah diekstrak (kemungkinan ada di folder Downloads).
  2. Klik dua kali pada folder project tersebut.
  3. Tunggu Android Studio membuka project.
  4. Klik tombol Run j7ptomO2PEQNe8jFt4nKCOw_Oc_Aucgf4l_La8fGLCMLy0t9RN9SkmBFGOFjkEzlX4ce2w2NWq4J30sDaxEe4MaSNuJPpMgHxnsRYoBtIV3-GUpYYcIvRJ2HrqR27XGuTS4F7lKCzg untuk membuat dan menjalankan aplikasi. Pastikan aplikasi berfungsi seperti yang diharapkan.
  5. Cari file project di jendela fitur Project untuk melihat cara aplikasi diterapkan.

Setiap aktivitas memiliki tahapan yang dikenal sebagai siklus proses. Tahapan ini adalah menggambarkan siklus proses tanaman dan hewan, seperti siklus hidup kupu-kupu ini—keadaan kupu-kupu yang berbeda menunjukkan pertumbuhannya mulai dari lahir, kemudian dewasa, hingga mati.

c685f48ff799f0c9.png

Demikian pula, siklus proses aktivitas terdiri dari berbagai status yang dapat dijalankan oleh suatu aktivitas, mulai dari saat aktivitas pertama kali diinisialisasi hingga dihancurkan dan memorinya diklaim kembali oleh sistem. Saat pengguna memulai aplikasi, berpindah antar-aktivitas, serta melakukan navigasi dalam dan di luar aplikasi Anda, aktivitas tersebut akan mengubah status. Diagram di bawah menunjukkan semua status siklus proses aktivitas. Seperti yang terlihat dari namanya, status ini menyatakan status aktivitas.

c803811f4cb4034b.png

Sering kali, Anda ingin mengubah beberapa perilaku, atau menjalankan beberapa kode saat status siklus proses aktivitas berubah. Oleh karena itu, class Activity itu sendiri, dan subclass Activity seperti AppCompatActivity, menerapkan sekumpulan metode callback siklus proses. Android mengaktifkan callback ini saat aktivitas berpindah dari satu status ke status lainnya, dan Anda dapat mengganti metode tersebut dalam aktivitas Anda sendiri untuk menjalankan tugas sebagai respons terhadap perubahan status siklus proses tersebut. Diagram berikut menampilkan status siklus proses beserta callback yang bisa diganti.

f6b25a71cec4e401.png

Penting untuk mengetahui waktu pemanggilan callback ini dan tugas yang harus dilakukan di setiap metode callback. Namun kedua diagram ini rumit dan mungkin membingungkan. Dalam codelab ini, Anda tidak hanya membaca arti setiap status dan callback, tetapi juga melakukan beberapa pekerjaan menyelidiki dan membangun pemahaman Anda tentang situasi yang terjadi.

Langkah 1: Memeriksa metode onCreate() dan menambahkan logging

Untuk mengetahui aktivitas siklus proses Android, sebaiknya ketahui waktu pemanggilan berbagai metode siklus proses. Ini akan membantu Anda berburu berbagai tempat yang tidak beres di aplikasi DessertClicker.

Cara sederhana untuk melakukannya adalah menggunakan fungsionalitas logging Android. Dengan logging, Anda dapat menulis pesan singkat ke konsol saat aplikasi berjalan, dan menggunakannya untuk menampilkan Anda saat memicu callback yang berbeda.

  1. Jalankan aplikasi DessertClicker, lalu ketuk gambar makanan penutup beberapa kali. Perhatikan perubahan nilai dari Makanan Penutup Terjual dan jumlah total uang dalam dolar.
  2. Buka MainActivity.kt dan periksa metode onCreate() untuk aktivitas ini:
override fun onCreate(savedInstanceState: Bundle?) {
...
}

Dalam diagram siklus proses aktivitas, Anda mungkin telah mengenali metode onCreate(), karena Anda sudah pernah menggunakan callback ini sebelumnya. Ini adalah satu metode yang harus diterapkan setiap aktivitas. Metode onCreate() menjadi tempat wajib untuk melakukan inisialisasi satu kali untuk aktivitas Anda. Misalnya, dalam onCreate() Anda meng-inflate tata letak, menentukan pemroses klik, atau menyiapkan view binding.

9be2255ff49e0af8.png

Metode siklus proses onCreate() dipanggil satu kali, tepat setelah aktivitas diinisialisasi (saat objek Activity baru dibuat di memori). Setelah onCreate() dijalankan, aktivitas dianggap telah dibuat.

  1. Dalam metode onCreate(), tepat setelah panggilan ke super.onCreate(), tambahkan baris berikut.
Log.d("MainActivity", "onCreate Called")
  1. Impor class Log jika perlu (tekan Alt+Enter, atau Option+Enter pada Mac, lalu pilih Import.) Jika Anda mengaktifkan impor otomatis, proses ini akan terjadi secara otomatis.
import android.util.Log

Class Log menulis pesan ke Logcat. Logcat merupakan konsol untuk mencatat pesan. Pesan dari Android tentang aplikasi Anda akan muncul di sini, termasuk pesan yang Anda kirim secara eksplisit ke log dengan metode Log.d() atau metode class Log lainnya.

Ada tiga bagian untuk perintah ini:

  • Prioritas pesan log, yaitu seberapa penting pesan tersebut. Dalam kasus ini, metode Log.d() menulis pesan debug. Metode lain di class Log mencakup Log.i() untuk pesan informasi, Log.e() untuk error, Log.w() untuk peringatan, atau Log.v() untuk pesan verbose.
  • Log tag (parameter pertama), dalam hal ini adalah "MainActivity". Tag adalah string yang memungkinkan Anda menemukan pesan log dengan lebih mudah di Logcat. Tag biasanya berupa nama kelas.
  • Log pesan yang sebenarnya (parameter kedua), adalah string pendek bernama "onCreate called".

Konstanta waktu kompilasi adalah nilai yang tidak akan berubah. Gunakan const sebelum deklarasi variabel untuk menandainya sebagai konstanta waktu kompilasi.

  1. Kompilasi dan jalankan aplikasi DessertClicker. Anda tidak akan melihat perbedaan perilaku di aplikasi saat mengetuk makanan penutup. Di bagian bawah layar, Android Studio klik tab Logcat.

ff9c50376701877f.png

  1. Di jendela Logcat, ketik D/MainActivity pada kolom penelusuran.

bb0b78600cd47789.png

Logcat dapat berisi banyak pesan dan sebagian besar tidak berguna bagi Anda. Anda dapat memfilter entri Logcat dengan berbagai cara, tetapi menggunakan penelusuran adalah cara termudah. Anda telah menggunakan MainActivity sebagai tag log dalam kode. Oleh karena itu, Anda dapat menggunakan tag tersebut untuk memfilter log. Menambahkan D/ di awal menunjukkan bahwa ini adalah pesan debug yang dibuat oleh Log.d().

Pesan log Anda berisi tanggal dan waktu, nama paket (com.example.android.dessertclicker), tag log Anda (dengan D/ di awal), dan pesan yang sebenarnya. Anda tahu bahwa onCreate() telah dijalankan karena pesan ini muncul di log.

Langkah 2: Mengimplementasikan metode onStart()

Metode siklus proses onStart() dipanggil tepat setelah onCreate(). Setelah onStart() berjalan, aktivitas Anda akan terlihat di layar. Tidak seperti onCreate() yang hanya dipanggil sekali untuk menginisialisasi aktivitas Anda, onStart() dapat dipanggil beberapa kali dalam siklus proses aktivitas Anda.

385df4ce82ae2de9.png

Perlu diketahui bahwa onStart() dipasangkan dengan metode siklus proses onStop() yang sesuai. Jika pengguna memulai aplikasi Anda lalu kembali ke layar utama perangkat, aktivitas tersebut akan dihentikan dan tidak lagi terlihat di layar.

  1. Di Android Studio, dengan MainActivity.kt terbuka dan kursor ada di dalam class MainActivity, pilih Code > Override Methods atau tekan Control+o (Command+o pada Mac). Dialog akan muncul dan menampilkan daftar lengkap semua metode yang dapat Anda ganti di kelas ini. e1f2460242b2ae.png
  2. Mulai masukkan onStart untuk menelusuri metode yang tepat. Untuk men-scroll ke item yang cocok berikutnya, gunakan panah bawah. Pilih onStart() dari daftar, lalu klik Oke untuk menyisipkan kode pengganti boilerplate. Kode terlihat seperti ini:
override fun onStart() {
   super.onStart()
}
  1. Tambahkan konstanta berikut di tingkat teratas MainActivity.kt yang berada di atas deklarasi class, class MainActivity.
const val TAG = "MainActivity"
  1. Di dalam metode onStart(), tambahkan pesan log:
override fun onStart() {
   super.onStart()
   Log.d(TAG, "onStart Called")
}
  1. Kompilasi dan jalankan aplikasi DessertClicker, dan buka panel Logcat. Ketikkan D/MainActivity pada penelusuran untuk memfilter log. Perhatikan bahwa metode onCreate() dan onStart() dipanggil satu demi satu, dan aktivitas Anda akan terlihat di layar.
  2. Tekan tombol Layar utama di perangkat, lalu gunakan layar terbaru untuk kembali ke aktivitas. Perhatikan bahwa aktivitas dilanjutkan dari tempat terakhirnya, dengan semua nilai yang sama, dan onStart() dicatat dalam log untuk kedua kalinya di Logcat. Perhatikan juga bahwa metode onCreate() biasanya tidak dipanggil lagi.
16:19:59.125 31107-31107/com.example.android.dessertclicker D/MainActivity: onCreate Called
16:19:59.372 31107-31107/com.example.android.dessertclicker D/MainActivity: onStart Called
16:20:11.319 31107-31107/com.example.android.dessertclicker D/MainActivity: onStart Called

Langkah 3: Menambahkan laporan log lainnya

Pada langkah ini, Anda akan menerapkan logging untuk semua metode siklus proses lainnya.

  1. Ganti metode sisa siklus proses di MainActivity, dan tambahkan laporan log untuk setiap metode. Berikut kodenya:
override fun onResume() {
   super.onResume()
   Log.d(TAG, "onResume Called")
}

override fun onPause() {
   super.onPause()
   Log.d(TAG, "onPause Called")
}

override fun onStop() {
   super.onStop()
   Log.d(TAG, "onStop Called")
}

override fun onDestroy() {
   super.onDestroy()
   Log.d(TAG, "onDestroy Called")
}

override fun onRestart() {
   super.onRestart()
   Log.d(TAG, "onRestart Called")
}
  1. Kompilasi dan jalankan lagi aplikasi DessertClicker dan periksa Logcat. Kali ini, selain onCreate() dan onStart(), ada pesan log untuk callback siklus proses onResume().
2020-10-16 10:27:33.244 22064-22064/com.example.android.dessertclicker D/MainActivity: onCreate Called
2020-10-16 10:27:33.453 22064-22064/com.example.android.dessertclicker D/MainActivity: onStart Called
2020-10-16 10:27:33.454 22064-22064/com.example.android.dessertclicker D/MainActivity: onResume Called

Saat aktivitas dimulai dari awal, Anda akan melihat ketiga callback siklus proses ini dipanggil secara berurutan:

  • onCreate() untuk membuat aplikasi.
  • onStart() untuk memulainya dan menampilkannya di layar.
  • onResume() untuk memberikan fokus pada aktivitas dan mempersiapkan pengguna untuk berinteraksi dengannya.

Terlepas dari namanya, metode onResume() akan dipanggil saat startup meskipun tidak ada yang dapat dilanjutkan.

160054d59f67519.png

Sekarang, setelah aplikasi DessertClicker disiapkan untuk logging, Anda siap untuk mulai menggunakan aplikasi dengan berbagai cara, dan juga mempelajari cara memicu callback siklus proses sebagai respons terhadap penggunaan tersebut.

Kasus penggunaan 1: Membuka dan menutup aktivitas

Mulailah dengan kasus penggunaan yang paling dasar, yaitu memulai aplikasi untuk pertama kali, lalu tutup aplikasi.

  1. Kompilasi dan jalankan aplikasi DessertClicker jika belum berjalan. Seperti yang Anda lihat, callback onCreate(), onStart(), dan onResume() dipanggil saat aktivitas dimulai pertama kali.
2020-10-16 10:27:33.244 22064-22064/com.example.android.dessertclicker D/MainActivity: onCreate Called
2020-10-16 10:27:33.453 22064-22064/com.example.android.dessertclicker D/MainActivity: onStart Called
2020-10-16 10:27:33.454 22064-22064/com.example.android.dessertclicker D/MainActivity: onResume Called
  1. Ketuk cupcake beberapa kali.
  2. Ketuk tombol Kembali yang ada di perangkat. Perhatikan dalam Logcat bahwa onPause(), onStop(), dan onDestroy() dipanggil dalam urutan tersebut.
2020-10-16 10:31:53.850 22064-22064/com.example.android.dessertclicker D/MainActivity: onPause Called
2020-10-16 10:31:54.620 22064-22064/com.example.android.dessertclicker D/MainActivity: onStop Called
2020-10-16 10:31:54.622 22064-22064/com.example.android.dessertclicker D/MainActivity: onDestroy Called

Dalam hal ini, menggunakan tombol Kembali akan menyebabkan aktivitas (dan aplikasi) ditutup. Eksekusi metode onDestroy() berarti aktivitas telah benar-benar dinonaktifkan dan sampah memori dapat dibersihkan. Pembersihan sampah memori mengacu pada pembersihan objek yang tidak akan digunakan lagi secara otomatis. Setelah onDestroy() dipanggil, sistem akan mengetahui bahwa resource tersebut dapat dihapus, dan memori akan mulai dibersihkan. 2dcc4d9c6478a9f4.png Aktivitas Anda juga dapat dinonaktifkan total jika kode Anda memanggil metode finish() aktivitas secara manual, atau jika pengguna menutup aplikasi secara paksa (misalnya, pengguna dapat menutup paksa atau menutup aplikasi di layar terbaru.) Sistem Android juga dapat menghentikan aktivitas Anda jika aplikasi tidak digunakan untuk waktu yang lama. Android melakukan hal ini untuk menghemat baterai, dan memungkinkan resource aplikasi Anda digunakan oleh aplikasi lain.

  1. Kembali ke aplikasi DessertClicker dengan menemukan semua aplikasi yang terbuka di layar Ringkasan. (Perhatikan bahwa ini juga dikenal sebagai layar Terbaru atau aplikasi terbaru.) Berikut Logcat-nya:
2020-10-16 10:31:54.622 22064-22064/com.example.android.dessertclicker D/MainActivity: onDestroy Called
2020-10-16 10:38:00.733 22064-22064/com.example.android.dessertclicker D/MainActivity: onCreate Called
2020-10-16 10:38:00.787 22064-22064/com.example.android.dessertclicker D/MainActivity: onStart Called
2020-10-16 10:38:00.788 22064-22064/com.example.android.dessertclicker D/MainActivity: onResume Called

Aktivitas ini dihancurkan pada langkah sebelumnya sehingga saat Anda kembali ke aplikasi, Android akan memulai aktivitas baru dan memanggil metode onCreate(), onStart(), dan onResume(). Perhatikan bahwa tidak satu pun log DessertClicker dari aktivitas sebelumnya yang disimpan.

Metode onCreate() merupakan langkah penting karena digunakan sebagai tempat inisialisasi pertama kali dilakukan, menyiapkan tata letak untuk pertama kalinya dengan meng-inflate-nya, dan menginisialisasi variabel.

Kasus penggunaan 2: Bernavigasi dari dan kembali ke aktivitas

Setelah memulai aplikasi lalu menutupnya dengan sempurna, Anda telah melihat sebagian besar status siklus proses saat aktivitas dibuat untuk pertama kalinya. Anda juga telah melihat semua status siklus proses yang dilewati saat aktivitas tersebut dinonaktifkan dan dimusnahkan. Namun saat pengguna berinteraksi dengan perangkat Android, mereka berpindah antar-aplikasi, kembali ke beranda, memulai aplikasi baru, dan menangani gangguan karena aktivitas lain seperti panggilan telepon.

Aktivitas Anda tidak benar-benar ditutup setiap kali pengguna keluar dari aktivitas tersebut:

  • Jika aktivitas Anda tidak lagi terlihat di layar, tindakan ini artinya aktivitas tersebut berada di latar belakang. (Kebalikannya adalah saat aktivitas berada di latar depan atau di layar.)
  • Saat pengguna kembali ke aplikasi Anda, aktivitas yang sama akan dimulai ulang dan akan terlihat lagi. Bagian siklus proses ini disebut siklus proses aplikasi yang terlihat.

Jika berada di latar belakang, aplikasi Anda seharusnya tidak aktif berjalan karena ingin mempertahankan resource sistem dan masa pakai baterai. Anda menggunakan siklus proses Activity dan callback untuk mengetahui waktu pemindahan aplikasi ke latar belakang sehingga Anda dapat menjeda operasi yang sedang berlangsung. Kemudian, mulai ulang operasi ketika aplikasi muncul di latar depan.

Pada langkah ini, Anda melihat siklus proses aktivitas saat aplikasi muncul di latar belakang dan kembali lagi ke latar depan.

  1. Dengan aplikasi DessertClicker masih berjalan, klik cupcake beberapa kali.
  2. Tekan tombol Beranda di perangkat dan amati Logcat di Android Studio. Saat Anda kembali ke layar utama, aplikasi tersebut tidak akan dimatikan, tetapi akan tetap berjalan di latar belakang. Perhatikan bahwa metode onPause() dan metode onStop() dipanggil, tetapi onDestroy() tidak.
2020-10-16 10:41:05.383 22064-22064/com.example.android.dessertclicker D/MainActivity: onPause Called
2020-10-16 10:41:05.966 22064-22064/com.example.android.dessertclicker D/MainActivity: onStop Called

Saat onPause() dipanggil, aplikasi tidak lagi memiliki fokus. Setelah onStop(), aplikasi tidak lagi akan terlihat di layar. Meskipun aktivitas telah dihentikan, objek Activity masih ada di memori, yakni di latar belakang. Aktivitas belum dimusnahkan. Pengguna mungkin kembali ke aplikasi. Jadi karena alasan ini, Android menyimpan resource aktivitas Anda. b488b32801220b79.png

  1. Gunakan layar terbaru untuk kembali ke aplikasi. Perhatikan di Logcat bahwa aktivitas dimulai ulang dengan onRestart() dan onStart(), lalu dilanjutkan dengan onResume().
2020-10-16 10:42:18.144 22064-22064/com.example.android.dessertclicker D/MainActivity: onRestart Called
2020-10-16 10:42:18.158 22064-22064/com.example.android.dessertclicker D/MainActivity: onStart Called
2020-10-16 10:42:18.158 22064-22064/com.example.android.dessertclicker D/MainActivity: onResume Called

Saat aktivitas kembali ke latar depan, metode onCreate() tidak akan dipanggil lagi. Objek aktivitas tidak dimusnahkan sehingga tidak perlu dibuat lagi. Sebagai ganti onCreate(), metode onRestart() dipanggil. Perhatikan saat sekarang aktivitas kembali ke latar depan, jumlah Makanan Penutup yang Terjual tetap dipertahankan.

  1. Mulai dengan minimal satu aplikasi selain DessertClicker sehingga ada beberapa aplikasi di layar terbaru perangkat.
  2. Munculkan layar terbaru dan buka aktivitas terbaru lainnya. Kemudian, kembali ke aplikasi terbaru dan pindahkan DessertClicker ke latar depan.

Perhatikan bahwa di sini Anda melihat callback yang juga Anda lihat di Logcat saat Anda menekan tombol Beranda. onPause() dan onStop() dipanggil saat aplikasi berpindah ke latar belakang, lalu onRestart(), onStart(), dan onResume() saat aplikasi kembali.

Metode ini dipanggil saat aplikasi dihentikan dan dipindahkan ke latar belakang, atau saat aplikasi dimulai lagi ketika kembali ke latar depan. Jika Anda perlu melakukan beberapa pekerjaan di aplikasi selama proses ini, ganti metode callback siklus proses yang relevan.

Jadi, bagaimana dengan onRestart()? Metode onRestart() mirip dengan onCreate(). onCreate() atau onRestart() dipanggil sebelum aktivitas terlihat. Metode onCreate() dipanggil hanya pada saat pertama, dan onRestart() dipanggil setelah itu. Metode onRestart() adalah tempat untuk meletakkan kode yang hanya ingin Anda panggil jika aktivitas tidak dimulai untuk pertama kalinya.

Kasus penggunaan 3: Menyembunyikan sebagian aktivitas

Anda telah mempelajari bahwa saat aplikasi dimulai dan onStart() dipanggil, aplikasi akan terlihat di layar. Saat aplikasi dilanjutkan dan onResume() dipanggil, pengguna akan berfokus ke aplikasi, yaitu pengguna dapat berinteraksi dengan aplikasi. Bagian siklus proses aplikasi yang menampilkan aplikasi di layar penuh dan mendapatkan fokus pengguna disebut siklus hidup interaktif.

Saat aplikasi berpindah ke latar belakang, fokus akan hilang setelah onPause(), dan aplikasi tidak lagi terlihat setelah onStop().

Perbedaan antara fokus dan visibilitas sangat penting karena ada kemungkinan aktivitas terlihat sebagian di layar, tetapi tidak mendapatkan fokus pengguna. Pada langkah ini, Anda melihat satu kasus saat aktivitas terlihat sebagian, tetapi tidak mendapatkan fokus pengguna.

  1. Dengan aplikasi DessertClicker masih berjalan, klik tombol Bagikan di kanan atas layar.
  2. Aktivitas berbagi muncul di paruh bawah layar, tetapi aktivitas tersebut juga masih terlihat di paruh atas. e2319779260eb5ee.png

9ddc8b1dc79b1bff.png

  1. Periksa Logcat dan perhatikan bahwa hanya onPause() yang dipanggil.
2020-10-16 11:00:53.857 22064-22064/com.example.android.dessertclicker D/MainActivity: onPause Called

Dalam kasus penggunaan ini, onStop() tidak dipanggil karena aktivitas masih terlihat sebagian. Namun, aktivitas tersebut tidak mendapatkan fokus pengguna, dan pengguna tidak dapat berinteraksi dengannya—aktivitas "berbagi" yang ada di latar depan mendapatkan fokus pengguna.

Mengapa perbedaan ini penting? Gangguan dengan onPause() saja biasanya berlangsung dalam waktu singkat sebelum kembali ke aktivitas atau membuka aktivitas atau aplikasi lain. Anda biasanya ingin terus mengupdate UI sehingga bagian aplikasi lainnya tidak akan berhenti berfungsi.

Kode apa pun yang berjalan di onPause() akan memblokir aplikasi lain agar tidak ditampilkan. Jadi, pastikan kode dalam mode onPause() selalu ringan. Misalnya, jika panggilan telepon masuk, kode dalam onPause() dapat menunda notifikasi panggilan masuk.

  1. Klik di luar dialog berbagi untuk kembali ke aplikasi, dan perhatikan bahwa onResume() dipanggil.

Baik onResume() maupun onPause() harus memiliki fokus. Metode onResume() dipanggil saat aktivitas memiliki fokus, dan onPause() dipanggil saat aktivitas kehilangan fokus.

Ada kasus lain dalam mengelola siklus proses aktivitas yang penting untuk dipahami: bagaimana perubahan konfigurasi memengaruhi siklus proses aktivitas Anda.

Perubahan konfigurasi terjadi saat status perangkat berubah secara drastis sehingga cara termudah bagi sistem untuk menyelesaikan perubahan adalah dengan benar-benar menonaktifkan dan membuat ulang aktivitas. Misalnya, jika pengguna mengubah bahasa perangkat, seluruh tata letak mungkin perlu diubah untuk mengakomodasi arah teks dan panjang string yang berbeda. Jika pengguna mencolokkan perangkat ke dok atau menambahkan keyboard fisik, tata letak aplikasi mungkin perlu memanfaatkan ukuran tampilan atau tata letak yang berbeda. Selain itu juga, jika orientasi perangkat berubah—jika perangkat diputar dari mode potret ke mode lanskap atau ke belakang, ataupun sebaliknya—tata letak mungkin perlu diubah agar sesuai dengan orientasi baru. Mari lihat perilaku aplikasi dalam skenario ini.

Kehilangan data di rotasi perangkat

  1. Kompilasi dan jalankan aplikasi Anda, lalu buka Logcat.
  2. Memutar perangkat atau emulator ke mode lanskap. Anda dapat memutar emulator ke kiri atau ke kanan dengan tombol rotasi, atau dengan tombol Control dan panah (Command dan tombol panah di Mac). 623fce7c623d42bd.png
  3. Periksa output di Logcat. Filter output di MainActivity.
2020-10-16 11:03:09.618 23206-23206/com.example.android.dessertclicker D/MainActivity: onCreate Called
2020-10-16 11:03:09.806 23206-23206/com.example.android.dessertclicker D/MainActivity: onStart Called
2020-10-16 11:03:09.808 23206-23206/com.example.android.dessertclicker D/MainActivity: onResume Called
2020-10-16 11:03:24.488 23206-23206/com.example.android.dessertclicker D/MainActivity: onPause Called
2020-10-16 11:03:24.490 23206-23206/com.example.android.dessertclicker D/MainActivity: onStop Called
2020-10-16 11:03:24.493 23206-23206/com.example.android.dessertclicker D/MainActivity: onDestroy Called
2020-10-16 11:03:24.520 23206-23206/com.example.android.dessertclicker D/MainActivity: onCreate Called
2020-10-16 11:03:24.569 23206-23206/com.example.android.dessertclicker D/MainActivity: onStart Called

Perhatikan bahwa saat perangkat atau emulator memutar layar, sistem akan memanggil semua callback siklus proses untuk menghentikan aktivitas. Kemudian, saat aktivitas dibuat ulang, sistem akan memanggil semua callback siklus proses untuk memulai aktivitas.

  1. Saat perangkat diputar dan aktivitas dinonaktifkan serta dibuat ulang, aktivitas akan dimulai dengan nilai default—jumlah makanan penutup yang terjual dan pendapatan telah disetel ulang menjadi nol.

Menggunakan onSaveInstanceState() untuk menyimpan data paket

Metode onSaveInstanceState() adalah callback yang Anda gunakan untuk menyimpan data yang mungkin diperlukan jika Activity dihancurkan. Dalam diagram callback siklus proses, onSaveInstanceState() akan dipanggil setelah aktivitas dihentikan. Kode tersebut akan dipanggil setiap kali aplikasi Anda masuk ke latar belakang.

c259ab6beca0ca88.png

Anggaplah panggilan onSaveInstanceState() sebagai tindakan keamanan; sehingga Anda dapat menyimpan sejumlah kecil informasi ke paket karena aktivitas Anda di latar depan ditutup. Sistem menyimpan data ini sekarang karena jika menunggu hingga aplikasi Anda dinonaktifkan, sistem dapat berada dalam tekanan resource.

Menyimpan data secara rutin akan membantu memastikan bahwa data yang diperbarui dalam paket dapat dipulihkan, jika diperlukan.

  1. Dalam MainActivity, ganti callback onSaveInstanceState(), dan tambahkan pernyataan log.
override fun onSaveInstanceState(outState: Bundle) {
   super.onSaveInstanceState(outState)

   Log.d(TAG, "onSaveInstanceState Called")
}
  1. Kompilasi dan jalankan aplikasi, lalu klik tombol Beranda untuk memindahkannya ke latar belakang. Perhatikan bahwa callback onSaveInstanceState() muncul tepat setelah onPause() dan onStop():
2020-10-16 11:05:21.726 23415-23415/com.example.android.dessertclicker D/MainActivity: onPause Called
2020-10-16 11:05:22.382 23415-23415/com.example.android.dessertclicker D/MainActivity: onStop Called
2020-10-16 11:05:22.393 23415-23415/com.example.android.dessertclicker D/MainActivity: onSaveInstanceState Called
  1. Di bagian atas file, tepat sebelum definisi class, tambahkan konstanta ini:
const val KEY_REVENUE = "revenue_key"
const val KEY_DESSERT_SOLD = "dessert_sold_key"

Anda akan menggunakan kunci ini untuk menyimpan dan mengambil data dari paket status instance.

  1. Scroll ke bawah ke onSaveInstanceState(), dan perhatikan parameter outState yang berjenis Bundle.

Bundle adalah kumpulan key-value pair dengan kunci selalu berupa string. Anda dapat memasukkan data sederhana, seperti nilai Int dan Boolean, ke dalam paket. Sistem tersebut menyimpan paket ini dalam memori sehingga cara terbaiknya adalah dengan menjaga data dalam paket tetap berukuran kecil. Ukuran paket ini juga terbatas, meskipun ukurannya bervariasi di setiap perangkat. Jika Anda menyimpan terlalu banyak data, Aplikasi Anda berisiko mengalami error karena kesalahan TransactionTooLargeException. 5. Dalam onSaveInstanceState(), masukkan nilai revenue (bilangan bulat) ke dalam paket dengan metode putInt():

outState.putInt(KEY_REVENUE, revenue)

Metode putInt() (dan metode serupa dari class Bundle seperti putFloat() dan putString() membutuhkan dua argumen: string untuk kunci (konstanta KEY_REVENUE) dan nilai aktual untuk disimpan.

  1. Ulangi proses yang sama dengan jumlah makanan penutup yang terjual:
outState.putInt(KEY_DESSERT_SOLD, dessertsSold)

Menggunakan onCreate() untuk memulihkan data paket

Status Aktivitas dapat dipulihkan dalam onCreate(Bundle) atau onRestoreInstanceState(Bundle) (metode Bundle yang diisi oleh onSaveInstanceState() akan diteruskan ke kedua metode callback siklus proses).

  1. Scroll sampai onCreate(), dan periksa tanda tangan metode:
override fun onCreate(savedInstanceState: Bundle) {

Perhatikan bahwa onCreate() akan mendapatkan Bundle setiap kali dipanggil. Saat aktivitas dimulai ulang karena proses penghentian, paket yang Anda simpan akan diteruskan ke onCreate(). Jika aktivitas Anda dimulai kembali dari awal, Bundle dalam onCreate() adalah null. Jadi, jika paket bukan null, Anda tahu bahwa Anda sedang "membuat ulang" aktivitas dari titik yang sebelumnya telah diketahui.

  1. Tambahkan kode ini ke onCreate(), tepat setelah variabel binding ditetapkan:
if (savedInstanceState != null) {
   revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
}

Pengujian null menentukan apakah ada data dalam paket, atau apakah paket tersebut adalah null, yang memberi tahu Anda bahwa aplikasi telah dimulai kembali dari awal atau telah dibuat ulang setelah penghentian. Pengujian ini adalah pola umum untuk memulihkan data dari paket.

Perhatikan bahwa kunci yang Anda gunakan di sini (KEY_REVENUE) adalah kunci yang sama dengan yang Anda gunakan untuk putInt(). Cara untuk memastikan Anda menggunakan kunci yang sama setiap saat adalah dengan mendefinisikan kunci tersebut sebagai konstanta. Anda menggunakan getInt() untuk mengeluarkan data dari paket, sama seperti Anda menggunakan putInt() untuk memasukkan data ke dalam paket. Metode getInt() menggunakan dua argumen:

  • String yang berfungsi sebagai kunci, misalnya "key_revenue" untuk nilai pendapatan.
  • Nilai default akan digunakan jika tidak ada nilai untuk kunci tersebut dalam paket.

Bilangan bulat yang Anda dapatkan dari paket tersebut selanjutnya akan ditetapkan ke variabel revenue, dan UI akan menggunakan nilai tersebut.

  1. Tambahkan metode getInt() untuk memulihkan pendapatan dan jumlah makanan penutup yang terjual.
if (savedInstanceState != null) {
   revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
   dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
}
  1. Kompilasi dan jalankan aplikasi. Tekan cupcake minimal lima kali hingga beralih ke donat.
  2. Putar perangkat. Perhatikan bahwa kali ini aplikasi menampilkan nilai pendapatan dan makanan penutup terjual yang benar dari paket. Perhatikan juga makanan penutup telah kembali ke cupcake. 4179956182ffc634.png Ada satu hal lagi yang harus dilakukan untuk memastikan bahwa aplikasi kembali ke keadaan terakhir sebelum mati.
  3. Dalam MainActivity, periksa metode showCurrentDessert(). Perhatikan bahwa metode ini menentukan gambar makanan penutup yang akan ditampilkan dalam aktivitas berdasarkan jumlah makanan penutup yang terjual saat ini dan daftar makanan penutup di variabel allDesserts.
for (dessert in allDesserts) {
   if (dessertsSold >= dessert.startProductionAmount) {
       newDessert = dessert
   }
    else break
}

Metode ini mengandalkan jumlah makanan penutup yang terjual untuk memilih gambar yang tepat. Oleh karena itu, Anda tidak perlu melakukan apa pun untuk menyimpan referensi gambar dalam paket di onSaveInstanceState(). Dalam paket tersebut, Anda sudah menyimpan jumlah makanan penutup yang terjual.

  1. Dalam onCreate(), di blok yang memulihkan status dari paket, panggil showCurrentDessert():
 if (savedInstanceState != null) {
   revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
   dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
   showCurrentDessert()
}
  1. Kompilasi dan jalankan aplikasi, lalu putar layar. Perlu diperhatikan bahwa nilai untuk makanan penutup yang terjual, pendapatan total, dan gambar makanan penutup telah dipulihkan dengan benar.

Siklus proses aktivitas

  • Siklus proses aktivitas merupakan kumpulan status tempat aktivitas dimigrasikan. Siklus proses aktivitas dimulai saat aktivitas pertama kali dibuat dan berakhir saat aktivitas dimusnahkan.
  • Saat pengguna bernavigasi di antara aktivitas, di dalam dan di luar aplikasi, setiap aktivitas bergerak antar keadaan dalam daur hidup aktivitas.
  • Setiap status dalam siklus proses aktivitas memiliki metode callback yang sesuai dan dapat Anda ganti di class Activity. Rangkaian inti dari metode siklus proses adalah: onCreate()onStart()onPause()onRestart()onResume()onStop()onDestroy()
  • Untuk menambahkan perilaku yang terjadi saat proses transisi aktivitas Anda ke status siklus proses, ganti metode callback status.
  • Untuk menambahkan metode penggantian kerangka ke class di Android Studio, pilih Code > Override Methods atau tekan Control+o (Command+o di Mac)

Melakukan Logging dengan Log

  • Dengan Logging API Android, dan khususnya class Log, Anda dapat menulis pesan singkat yang ditampilkan di Logcat dalam Android Studio.
  • Gunakan Log.d() untuk menulis pesan debug. Metode ini menggunakan dua argumen: tag log yang biasanya berupa nama kelas, dan pesan log yang berupa string singkat.
  • Gunakan jendela Logcat di Android Studio untuk melihat log sistem, termasuk pesan yang Anda tulis.

Mempertahankan status aktivitas

  • Saat aplikasi Anda berpindah ke latar belakang, tepat setelah onStop() dipanggil, data aplikasi dapat disimpan ke paket. Beberapa data aplikasi, seperti konten EditText, akan otomatis disimpan untuk Anda.
  • Paket tersebut adalah instance dari Bundle, yang merupakan kumpulan kunci dan nilai. Kunci selalu berupa string.
  • Gunakan callback onSaveInstanceState() untuk menyimpan data lain ke paket yang ingin Anda pertahankan, meskipun aplikasi tersebut dimatikan secara otomatis. Untuk memasukkan data ke dalam paket, gunakan metode paket yang dimulai dengan put, seperti putInt().
  • Anda bisa mendapatkan kembali data dari paket dalam metode onRestoreInstanceState(), atau yang lebih umum di onCreate(). Metode onCreate() memiliki parameter savedInstanceState penyimpanan paket.
  • Jika variabel savedInstanceState adalah null, aktivitas akan dimulai tanpa paket status dan tidak ada data status yang dapat diambil.
  • Untuk mengambil data dari paket menggunakan kunci, gunakan metode Bundle yang dimulai dengan get, seperti getInt().

Perubahan konfigurasi

  • Perubahan konfigurasi terjadi saat status perangkat berubah secara drastis sehingga cara termudah bagi sistem untuk menyelesaikan perubahan adalah dengan memusnahkan dan membuat ulang aktivitas.
  • Contoh paling umum dari perubahan konfigurasi adalah bila pengguna memutar perangkat dari mode potret ke mode lanskap, atau sebaliknya. Perubahan konfigurasi juga dapat terjadi saat bahasa perangkat berubah atau keyboard hardware dicolokkan.
  • Saat terjadi perubahan konfigurasi, Android akan memanggil semua callback penonaktifan siklus proses aktivitas. Kemudian, Android akan memulai ulang aktivitas dari awal, menjalankan semua callback startup siklus hidup.
  • Saat Android menutup aplikasi karena perubahan konfigurasi, aplikasi akan memulai ulang aktivitas menggunakan paket status yang tersedia untuk onCreate().
  • Seperti halnya penonaktifan proses, simpan status aplikasi Anda ke paket di onSaveInstanceState().