Codelab ini adalah bagian dari kursus Dasar-Dasar Android Kotlin. Anda akan mendapatkan manfaat maksimal dari kursus ini jika menyelesaikan codelab secara berurutan. Semua codelab kursus tercantum di halaman landing codelab Dasar-Dasar Android Kotlin.
Pengantar
Dalam codelab terakhir, Anda telah mempelajari siklus proses Activity
dan Fragment
, serta menjelajahi metode yang dipanggil saat status siklus proses berubah dalam aktivitas dan fragmen. Dalam codelab ini, Anda akan mempelajari siklus proses aktivitas secara lebih mendetail. Anda juga akan mempelajari library siklus proses Android Jetpack, yang dapat membantu Anda mengelola peristiwa siklus proses dengan kode yang lebih teratur dan lebih mudah dikelola.
Yang harus sudah Anda ketahui
- Pengertian aktivitas, dan cara membuatnya di aplikasi Anda.
- Dasar-dasar siklus proses
Activity
danFragment
, serta callback yang dipanggil saat aktivitas berpindah antar-status. - Cara mengganti metode callback siklus proses
onCreate()
danonStop()
untuk menjalankan operasi pada waktu yang berbeda dalam siklus proses aktivitas atau fragmen.
Yang akan Anda pelajari
- Cara menyiapkan, memulai, dan menghentikan bagian aplikasi Anda dalam callback siklus proses.
- Cara menggunakan library siklus proses Android untuk membuat pengamat siklus proses, dan mempermudah pengelolaan siklus proses aktivitas dan fragmen.
- Bagaimana penonaktifan proses Android memengaruhi data di aplikasi Anda, dan cara menyimpan serta memulihkan data tersebut secara otomatis saat Android menutup aplikasi Anda.
- Cara rotasi perangkat dan perubahan konfigurasi lainnya membuat perubahan pada status siklus proses dan memengaruhi status aplikasi Anda.
Yang akan Anda lakukan
- Ubah aplikasi DessertClicker untuk menyertakan fungsi timer, serta mulai dan hentikan timer tersebut pada berbagai waktu dalam siklus proses aktivitas.
- Ubah aplikasi untuk menggunakan library siklus proses Android, dan konversi class
DessertTimer
menjadi pengamat siklus proses. - Siapkan dan gunakan Android Debug Bridge (
adb
) untuk menyimulasikan penonaktifan proses aplikasi Anda dan callback siklus proses yang terjadi saat itu. - Menerapkan metode
onSaveInstanceState()
untuk mempertahankan data aplikasi yang mungkin hilang jika aplikasi ditutup secara tidak terduga. Menambahkan kode untuk memulihkan data tersebut saat aplikasi dimulai lagi.
Dalam codelab ini, Anda akan memperluas aplikasi DessertClicker dari codelab sebelumnya. Anda menambahkan timer latar belakang, lalu mengonversi aplikasi untuk menggunakan library siklus proses Android.
Dalam codelab sebelumnya, Anda telah mempelajari cara mengamati siklus proses aktivitas dan fragmen dengan mengganti berbagai callback siklus proses, dan mencatat saat sistem memanggil callback tersebut. Dalam tugas ini, Anda akan mempelajari contoh yang lebih kompleks tentang cara mengelola tugas siklus proses di aplikasi DessertClicker. Anda akan menggunakan timer yang mencetak pernyataan log setiap detik, dengan jumlah detik yang telah berjalan.
Langkah 1: Siapkan DessertTimer
- Buka aplikasi DessertClicker dari codelab terakhir. (Anda dapat mendownload DessertClickerLogs di sini jika tidak memiliki aplikasi.)
- Pada tampilan Project, luaskan java > com.example.android.dessertclicker dan buka
DessertTimer.kt
. Perhatikan bahwa saat ini semua kode dikomentari, sehingga tidak berjalan sebagai bagian dari aplikasi. - Pilih semua kode di jendela editor. Pilih Code > Comment with Line Comment, atau tekan
Control+/
(Command+/
di Mac). Perintah ini akan menghilangkan komentar pada semua kode dalam file. (Android Studio mungkin menampilkan error referensi yang belum terselesaikan hingga Anda membangun ulang aplikasi.) - Perhatikan bahwa class
DessertTimer
mencakupstartTimer()
danstopTimer()
, yang memulai dan menghentikan timer. SaatstartTimer()
berjalan, timer mencetak pesan log setiap detik, dengan jumlah total detik waktu telah berjalan. MetodestopTimer()
, pada gilirannya, menghentikan timer dan pernyataan log.
- Buka
MainActivity.kt
. Di bagian atas class, tepat di bawah variabeldessertsSold
, tambahkan variabel untuk pewaktu:
private lateinit var dessertTimer : DessertTimer;
- Scroll ke bawah ke
onCreate()
dan buat objekDessertTimer
baru, tepat setelah panggilan kesetOnClickListener()
:
dessertTimer = DessertTimer()
Setelah memiliki objek timer makanan penutup, pertimbangkan di mana Anda harus memulai dan menghentikan timer agar berjalan hanya saat aktivitas ditampilkan di layar. Anda akan melihat beberapa opsi di langkah berikutnya.
Langkah 2: Mulai dan hentikan timer
Metode onStart()
dipanggil tepat sebelum aktivitas terlihat. Metode onStop()
dipanggil setelah aktivitas berhenti terlihat. Callback ini tampaknya merupakan kandidat yang baik untuk menentukan kapan harus memulai dan menghentikan timer.
- Di class
MainActivity
, mulai timer di callbackonStart()
:
override fun onStart() {
super.onStart()
dessertTimer.startTimer()
Timber.i("onStart called")
}
- Hentikan timer dalam
onStop()
:
override fun onStop() {
super.onStop()
dessertTimer.stopTimer()
Timber.i("onStop Called")
}
- Kompilasi dan jalankan aplikasi. Di Android Studio, klik panel Logcat. Di kotak penelusuran Logcat, masukkan
dessertclicker
, yang akan memfilter menurut classMainActivity
danDessertTimer
. Perhatikan bahwa setelah aplikasi dimulai, timer juga akan langsung berjalan. - Klik tombol Kembali dan perhatikan bahwa timer berhenti lagi. Timer berhenti karena aktivitas dan timer yang dikontrolnya telah ditutup.
- Gunakan layar terbaru untuk kembali ke aplikasi. Perhatikan di Logcat bahwa timer dimulai ulang dari 0.
- Klik tombol Bagikan. Perhatikan dalam Logcat bahwa timer masih berjalan.
- Klik tombol Beranda. Perhatikan di Logcat bahwa timer berhenti berjalan.
- Gunakan layar terbaru untuk kembali ke aplikasi. Perhatikan di Logcat bahwa timer dimulai lagi dari tempat terakhirnya.
- Di
MainActivity
, dalam metodeonStop()
, beri komentar pada panggilan kestopTimer()
. MengomentaristopTimer()
menunjukkan kasus saat Anda memulai operasi dionStart()
, tetapi lupa menghentikannya lagi dionStop()
. - Kompilasi dan jalankan aplikasi, lalu klik tombol Beranda setelah timer dimulai. Meskipun aplikasi berada di latar belakang, pewaktu tetap berjalan dan terus menggunakan resource sistem. Membiarkan timer terus berjalan adalah kebocoran memori untuk aplikasi Anda, dan mungkin bukan perilaku yang Anda inginkan.
Pola umumnya adalah saat Anda menyiapkan atau memulai sesuatu dalam callback, Anda menghentikan atau menghapus hal tersebut dalam callback yang sesuai. Dengan begitu, Anda tidak perlu menjalankan apa pun jika tidak diperlukan lagi.
- Hapus tanda komentar pada baris di
onStop()
tempat Anda menghentikan timer. - Potong dan tempelkan panggilan
startTimer()
darionStart()
keonCreate()
. Perubahan ini menunjukkan kasus saat Anda melakukan inisialisasi dan memulai resource dionCreate()
, bukan menggunakanonCreate()
untuk melakukan inisialisasi danonStart()
untuk memulainya. - Kompilasi dan jalankan aplikasi. Perhatikan bahwa timer mulai berjalan, seperti yang Anda harapkan.
- Klik Home untuk menghentikan aplikasi. Timer akan berhenti berjalan seperti yang Anda harapkan.
- Gunakan layar terbaru untuk kembali ke aplikasi. Perhatikan bahwa timer tidak dimulai lagi dalam kasus ini, karena
onCreate()
hanya dipanggil saat aplikasi dimulai—tidak dipanggil saat aplikasi kembali ke latar depan.
Poin penting yang perlu diingat:
- Saat Anda menyiapkan resource dalam callback siklus proses, hapus juga resource tersebut.
- Lakukan penyiapan dan penonaktifan dalam metode yang sesuai.
- Jika Anda menyiapkan sesuatu di
onStart()
, hentikan atau hapus lagi dionStop()
.
Di aplikasi DessertClicker, cukup mudah untuk melihat bahwa jika Anda memulai timer di onStart()
, Anda harus menghentikan timer di onStop()
. Hanya ada satu timer, jadi menghentikan timer tidak sulit untuk diingat.
Dalam aplikasi Android yang lebih kompleks, Anda dapat menyiapkan banyak hal di onStart()
atau onCreate()
, lalu menghapusnya semua di onStop()
atau onDestroy()
. Misalnya, Anda mungkin memiliki animasi, musik, sensor, atau timer yang perlu disiapkan dan dihentikan, serta dimulai dan dihentikan. Jika Anda lupa salah satunya, hal itu akan menyebabkan bug dan masalah.
Library siklus proses, yang merupakan bagian dari Android Jetpack, menyederhanakan tugas ini. Library ini sangat berguna jika Anda harus melacak banyak bagian yang bergerak, beberapa di antaranya berada dalam status siklus proses yang berbeda. Library membalikkan cara kerja siklus proses: Biasanya aktivitas atau fragmen memberi tahu komponen (seperti DessertTimer
) apa yang harus dilakukan saat callback siklus proses terjadi. Namun, saat Anda menggunakan library siklus proses, komponen itu sendiri akan memantau perubahan siklus proses, lalu melakukan apa yang diperlukan saat perubahan tersebut terjadi.
Ada tiga bagian utama library siklus proses:
- Pemilik siklus proses, yaitu komponen yang memiliki (dan dengan demikian "memiliki") siklus proses.
Activity
danFragment
adalah pemilik siklus proses. Pemilik siklus proses menerapkan antarmukaLifecycleOwner
. - Class
Lifecycle
, yang menyimpan status sebenarnya dari pemilik siklus proses dan memicu peristiwa saat perubahan siklus proses terjadi. - Observer siklus proses, yang mengamati status siklus proses dan melakukan tugas saat siklus proses berubah. Observer siklus proses menerapkan antarmuka
LifecycleObserver
.
Dalam tugas ini, Anda akan mengonversi aplikasi DessertClicker untuk menggunakan library siklus proses Android, dan mempelajari cara library mempermudah pengelolaan siklus proses aktivitas dan fragmen Android.
Langkah 1: Mengubah DessertTimer menjadi LifecycleObserver
Bagian penting dari library siklus proses adalah konsep pengamatan siklus proses. Observasi memungkinkan class (seperti DessertTimer
) mengetahui siklus proses aktivitas atau fragmen, serta memulai dan menghentikan dirinya sendiri sebagai respons terhadap perubahan status siklus proses tersebut. Dengan pengamat siklus proses, Anda dapat menghapus tanggung jawab untuk memulai dan menghentikan objek dari metode aktivitas dan fragmen.
- Buka class
DesertTimer.kt
. - Ubah tanda tangan class
DessertTimer
agar terlihat seperti ini:
class DessertTimer(lifecycle: Lifecycle) : LifecycleObserver {
Definisi class baru ini melakukan dua hal:
- Konstruktor mengambil objek
Lifecycle
, yang merupakan siklus proses yang diamati pewaktu. - Definisi class mengimplementasikan antarmuka
LifecycleObserver
.
- Di bawah variabel
runnable
, tambahkan blokinit
ke definisi class. Dalam blokinit
, gunakan metodeaddObserver()
untuk menghubungkan objek siklus proses yang diteruskan dari pemilik (aktivitas) ke class ini (pengamat).
init {
lifecycle.addObserver(this)
}
- Anotasikan
startTimer()
dengan@OnLifecycleEvent annotation
, dan gunakan peristiwa siklus prosesON_START
. Semua peristiwa siklus proses yang dapat diamati oleh pengamat siklus proses Anda ada di classLifecycle.Event
.
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun startTimer() {
- Lakukan hal yang sama pada
stopTimer()
, menggunakan peristiwaON_STOP
:
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun stopTimer()
Langkah 2: Ubah MainActivity
Class MainActivity
Anda sudah menjadi pemilik siklus proses melalui pewarisan, karena superclass FragmentActivity
mengimplementasikan LifecycleOwner
. Oleh karena itu, Anda tidak perlu melakukan apa pun untuk membuat siklus proses aktivitas Anda kompatibel dengan siklus proses. Yang perlu Anda lakukan adalah meneruskan objek siklus proses aktivitas ke konstruktor DessertTimer
.
- Buka
MainActivity
. Dalam metodeonCreate()
, ubah inisialisasiDessertTimer
untuk menyertakanthis.lifecycle
:
dessertTimer = DessertTimer(this.lifecycle)
Properti lifecycle
aktivitas menyimpan objek Lifecycle
yang dimiliki aktivitas ini.
- Hapus panggilan ke
startTimer()
dionCreate()
, dan panggilan kestopTimer()
dionStop()
. Anda tidak perlu lagi memberi tahuDessertTimer
apa yang harus dilakukan dalam aktivitas, karenaDessertTimer
kini mengamati siklus proses itu sendiri dan otomatis diberi tahu saat status siklus proses berubah. Yang Anda lakukan di callback ini sekarang adalah mencatat pesan. - Kompilasi dan jalankan aplikasi, lalu buka Logcat. Perhatikan bahwa timer telah mulai berjalan, seperti yang diharapkan.
- Klik tombol layar utama untuk memindahkan aplikasi ke latar belakang. Perhatikan bahwa timer telah berhenti berjalan, seperti yang diharapkan.
Apa yang terjadi pada aplikasi dan datanya jika Android mematikan aplikasi tersebut saat berada di latar belakang? Kasus berisiko yang rumit ini penting untuk dipahami.
Saat beralih ke latar belakang, aplikasi tidak ditutup, tetapi hanya berhenti dan menunggu pengguna untuk berinteraksi dengannya kembali. Namun, salah satu perhatian utama OS Android adalah menjaga agar aktivitas yang berada di latar depan berjalan lancar. Misalnya, jika pengguna Anda menggunakan aplikasi GPS untuk membantu mereka naik bus, penting untuk merender aplikasi GPS tersebut dengan cepat dan terus menampilkan petunjuk arah. Tidak terlalu penting untuk menjaga aplikasi DessertClicker, yang mungkin tidak dilihat pengguna selama beberapa hari, berjalan lancar di latar belakang.
Android mengatur aplikasi latar belakang sehingga aplikasi latar depan dapat berjalan tanpa masalah. Misalnya, Android membatasi jumlah pemrosesan yang dapat dilakukan oleh aplikasi yang berjalan di latar belakang.
Terkadang Android bahkan menghentikan seluruh proses aplikasi, yang mencakup setiap aktivitas yang terkait dengan aplikasi. Android melakukan penonaktifan seperti ini saat sistem mengalami gangguan dan berisiko mengalami keterlambatan secara visual sehingga tidak ada callback atau kode tambahan yang dijalankan saat ini. Proses aplikasi Anda dihentikan di latar belakang dengan diam-diam. Namun, bagi pengguna, sepertinya aplikasi tidak ditutup. Saat pengguna kembali ke aplikasi yang dihentikan oleh Android OS, Android akan memulai ulang aplikasi tersebut.
Dalam tugas ini, Anda akan menyimulasikan penonaktifan proses Android dan memeriksa apa yang terjadi pada aplikasi saat dimulai lagi.
Langkah 1: Gunakan adb untuk menyimulasikan penonaktifan proses
Android Debug Bridge (adb
) adalah alat command line yang memungkinkan Anda mengirimkan petunjuk ke emulator dan perangkat yang terhubung ke komputer Anda. Pada langkah ini, Anda menggunakan adb
untuk menutup proses aplikasi dan melihat apa yang terjadi saat Android menghentikan aplikasi Anda.
- Kompilasi dan jalankan aplikasi Anda. Klik cupcake beberapa kali.
- Tekan tombol Beranda untuk menempatkan aplikasi Anda ke latar belakang. Aplikasi Anda kini dihentikan, dan aplikasi dapat ditutup jika Android memerlukan resource yang sedang digunakan aplikasi.
- Di Android Studio, klik tab Terminal untuk membuka terminal command line.
- Ketik
adb
, lalu tekan Return.
Jika Anda melihat banyak output yang dimulai denganAndroid Debug Bridge version X.XX.X
dan diakhiri dengantags to be used by logcat (see logcat —h
elp), semuanya baik-baik saja. Jika Anda melihatadb: command not found
, pastikan perintahadb
tersedia di jalur eksekusi Anda. Untuk mengetahui petunjuknya, lihat "Menambahkan adb ke jalur eksekusi" di bab Utilitas. - Salin dan tempel komentar ini ke command line, lalu tekan Return:
adb shell am kill com.example.android.dessertclicker
Perintah ini memberi tahu perangkat atau emulator yang terhubung untuk menghentikan proses dengan nama paket dessertclicker
, tetapi hanya jika aplikasi berada di latar belakang. Karena aplikasi Anda berada di latar belakang, tidak ada yang ditampilkan di layar perangkat atau emulator untuk menunjukkan bahwa proses Anda telah dihentikan. Di Android Studio, klik tab Run untuk melihat pesan yang bertuliskan "Application terminated". Klik tab Logcat untuk melihat bahwa callback onDestroy()
tidak pernah dijalankan—aktivitas Anda berakhir begitu saja.
- Gunakan layar terbaru untuk kembali ke aplikasi. Aplikasi Anda akan muncul di layar terbaru, baik saat aplikasi telah ditempatkan di latar belakang maupun saat aplikasi telah dihentikan sepenuhnya. Saat Anda menggunakan layar terbaru untuk kembali ke aplikasi, aktivitas akan dimulai lagi. Aktivitas akan melalui seluruh rangkaian callback siklus proses startup, termasuk
onCreate()
. - Perhatikan bahwa saat aplikasi dimulai ulang, aplikasi akan mereset "skor" Anda (jumlah makanan penutup yang terjual dan total dolar) ke nilai default (0). Jika Android menutup aplikasi Anda, mengapa tidak menyimpan status Anda?
Saat OS memulai ulang aplikasi Anda, Android akan mencoba sebaik mungkin untuk mereset aplikasi Anda ke status yang dimilikinya sebelumnya. Android mengambil status beberapa tampilan Anda dan menyimpannya dalam paket setiap kali Anda keluar dari aktivitas. Beberapa contoh data yang disimpan secara otomatis adalah teks dalam EditText (selama ID-nya ditetapkan dalam tata letak), dan back stack aktivitas Anda.
Namun, terkadang Android OS tidak mengetahui semua data Anda. Misalnya, jika Anda memiliki variabel kustom sepertirevenue
di aplikasi DessertClicker, OS Android tidak mengetahui data ini atau kepentingannya bagi aktivitas Anda. Anda harus menambahkan data ini ke paket sendiri.
Langkah 2: Menggunakan onSaveInstanceState() untuk menyimpan data paket
Metode onSaveInstanceState()
adalah callback yang Anda gunakan untuk menyimpan data yang mungkin diperlukan jika Android OS menghancurkan aplikasi Anda. Dalam diagram callback siklus proses, onSaveInstanceState()
dipanggil setelah aktivitas dihentikan. Kode tersebut akan dipanggil setiap kali aplikasi Anda masuk ke latar belakang.
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, OS dapat berada dalam tekanan resource. Menyimpan data secara rutin akan membantu memastikan bahwa data yang diperbarui dalam paket dapat dipulihkan, jika diperlukan.
- Di
MainActivity
, ganti callbackonSaveInstanceState()
, dan tambahkan pernyataan logTimber
.
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Timber.i("onSaveInstanceState Called")
}
- Kompilasi dan jalankan aplikasi, lalu klik tombol Beranda untuk memindahkannya ke latar belakang. Perhatikan bahwa callback
onSaveInstanceState()
muncul tepat setelahonPause()
danonStop()
: - 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"
const val KEY_TIMER_SECONDS = "timer_seconds_key"
Anda akan menggunakan kunci ini untuk menyimpan dan mengambil data dari paket status instance.
- Scroll ke bawah ke
onSaveInstanceState()
, dan perhatikan parameteroutState
yang berjenisBundle
.
Bundle adalah kumpulan key-value pair, dengan kunci selalu berupa string. Anda dapat memasukkan nilai primitif, seperti nilaiint
danboolean
, ke dalam paket.
Karena sistem menyimpan paket ini dalam RAM, cara terbaiknya adalah dengan menjaga data dalam paket tetap berukuran kecil. Ukuran paket ini juga terbatas, meskipun ukurannya bervariasi di setiap perangkat. Biasanya Anda harus menyimpan jauh lebih sedikit dari 100 ribu, jika tidak, Anda berisiko membuat aplikasi Anda mengalami error karena errorTransactionTooLargeException
. - Dalam
onSaveInstanceState()
, masukkan nilairevenue
(bilangan bulat) ke dalam paket dengan metodeputInt()
:
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.
- Ulangi proses yang sama dengan jumlah makanan penutup yang terjual, dan status timer:
outState.putInt(KEY_DESSERT_SOLD, dessertsSold)
outState.putInt(KEY_TIMER_SECONDS, dessertTimer.secondsCount)
Langkah 3: Menggunakan onCreate() untuk memulihkan data paket
- Scroll sampai
onCreate()
, dan periksa tanda tangan metode:
override fun onCreate(savedInstanceState: Bundle) {
Perhatikan bahwa onCreate()
akan mendapatkan Bundle
setiap kali dipanggil. Saat aktivitas Anda dimulai ulang karena penghentian proses, paket yang Anda simpan akan diteruskan ke onCreate()
. Jika aktivitas Anda dimulai kembali dari awal, paket dalam onCreate()
ini adalah null
. Jadi, jika paket bukan null
, Anda tahu bahwa Anda sedang "membuat ulang" aktivitas dari titik yang sebelumnya telah diketahui.
- Tambahkan kode ini ke
onCreate()
, setelah penyiapanDessertTimer
:
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.
- Tambahkan metode
getInt()
untuk memulihkan jumlah makanan penutup yang terjual dan nilai timer:
if (savedInstanceState != null) {
revenue = savedInstanceState.getInt(KEY_REVENUE, 0)dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
dessertTimer.secondsCount =
savedInstanceState.getInt(KEY_TIMER_SECONDS, 0)
}
- Kompilasi dan jalankan aplikasi. Tekan cupcake minimal lima kali hingga beralih ke donat. Klik Beranda untuk memindahkan aplikasi ke latar belakang.
- Di tab Terminal Android Studio, jalankan
adb
untuk menghentikan proses aplikasi.
adb shell am kill com.example.android.dessertclicker
- Gunakan layar terbaru untuk kembali ke aplikasi. Perhatikan bahwa kali ini aplikasi kembali dengan nilai pendapatan dan makanan penutup terjual yang benar dari paket. Perhatikan juga makanan penutup telah kembali ke cupcake. Ada satu hal lagi yang harus dilakukan untuk memastikan bahwa aplikasi kembali ke keadaan terakhir sebelum mati.
- Dalam
MainActivity
, periksa metodeshowCurrentDessert()
. 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 variabelallDesserts
.
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.
- Di
onCreate()
, di blok yang memulihkan status dari paket, panggilshowCurrentDessert()
:
if (savedInstanceState != null) {
revenue = savedInstanceState.getInt(KEY_REVENUE, 0)
dessertsSold = savedInstanceState.getInt(KEY_DESSERT_SOLD, 0)
dessertTimer.secondsCount =
savedInstanceState.getInt(KEY_TIMER_SECONDS, 0)
showCurrentDessert()
}
- Kompilasi dan jalankan aplikasi, lalu pindahkan ke latar belakang. Gunakan
adb
untuk menghentikan proses. Gunakan layar terbaru untuk kembali ke aplikasi. Perhatikan bahwa nilai untuk makanan penutup yang terjual, pendapatan total, dan gambar makanan penutup telah dipulihkan dengan benar.
Ada satu kasus khusus terakhir dalam mengelola siklus proses aktivitas dan fragmen yang penting untuk dipahami: bagaimana perubahan konfigurasi memengaruhi siklus proses aktivitas dan fragmen 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 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 kembali sebaliknya—tata letak mungkin perlu diubah agar sesuai dengan orientasi baru.
Langkah 1: Jelajahi rotasi perangkat dan callback siklus proses
- Kompilasi dan jalankan aplikasi Anda, lalu buka Logcat.
- Putar 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). - Periksa output di Logcat. Filter output di
MainActivity
.
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. - Di
MainActivity
, beri komentar pada seluruh metodeonSaveInstanceState()
. - Kompilasi dan jalankan aplikasi Anda lagi. Klik cupcake beberapa kali, lalu putar perangkat atau emulator. Kali ini, saat perangkat diputar dan aktivitas dinonaktifkan serta dibuat ulang, aktivitas akan dimulai dengan nilai default.
Saat perubahan konfigurasi terjadi, Android menggunakan paket status instance yang sama yang Anda pelajari dalam tugas sebelumnya untuk menyimpan dan memulihkan status aplikasi. Seperti saat penonaktifan proses, gunakanonSaveInstanceState()
untuk memasukkan data aplikasi ke dalam paket. Kemudian, pulihkan data dionCreate()
, untuk menghindari hilangnya data status aktivitas jika perangkat diputar. - Di
MainActivity
, hapus komentar metodeonSaveInstanceState()
, jalankan aplikasi, klik cupcake, lalu putar aplikasi atau perangkat. Perhatikan bahwa kali ini data makanan penutup dipertahankan di seluruh rotasi aktivitas.
Project Android Studio: DessertClickerFinal
Tips siklus proses
- Jika Anda menyiapkan atau memulai sesuatu di callback siklus proses, hentikan atau hapus hal tersebut di callback yang sesuai. Dengan menghentikan perangkat, Anda memastikan perangkat tidak terus berjalan saat tidak lagi diperlukan. Misalnya, jika Anda menyiapkan timer di
onStart()
, Anda perlu menjeda atau menghentikan timer dionStop()
. - Gunakan
onCreate()
hanya untuk menginisialisasi bagian aplikasi yang berjalan satu kali, saat aplikasi pertama kali dimulai. GunakanonStart()
untuk memulai bagian aplikasi yang berjalan saat aplikasi dimulai, dan setiap kali aplikasi kembali ke latar depan.
Library siklus proses
- Gunakan library siklus proses Android untuk mengalihkan kontrol siklus proses dari aktivitas atau fragmen ke komponen sebenarnya yang harus berbasis siklus proses.
- Pemilik siklus proses adalah komponen yang memiliki (dan dengan demikian "memiliki") siklus proses, termasuk
Activity
danFragment
. Pemilik siklus proses menerapkan antarmukaLifecycleOwner
. - Observer siklus proses memperhatikan status siklus proses saat ini dan melakukan tugas saat siklus proses berubah. Observer siklus proses menerapkan antarmuka
LifecycleObserver
. - Objek
Lifecycle
berisi status siklus proses yang sebenarnya, dan memicu peristiwa saat siklus proses berubah.
Untuk membuat class yang kompatibel dengan siklus proses:
- Terapkan antarmuka
LifecycleObserver
di class yang perlu berbasis siklus proses. - Inisialisasi class pengamat siklus proses dengan objek siklus proses dari aktivitas atau fragmen.
- Di class observer siklus proses, anotasikan metode berbasis siklus proses dengan perubahan status siklus proses yang mereka minati.
Misalnya, anotasi@OnLifecycleEvent(Lifecycle.Event.ON_START)
menunjukkan bahwa metode sedang memantau peristiwa siklus prosesonStart
.
Penonaktifan proses dan penyimpanan status aktivitas
- Android mengatur aplikasi yang berjalan di latar belakang sehingga aplikasi latar depan dapat berjalan tanpa masalah. Peraturan ini mencakup pembatasan jumlah pemrosesan yang dapat dilakukan oleh aplikasi di latar belakang, dan terkadang bahkan mematikan seluruh proses aplikasi Anda.
- Pengguna tidak dapat mengetahui apakah sistem telah menutup aplikasi di latar belakang. Aplikasi masih muncul di layar terbaru dan harus dimulai ulang dalam status yang sama seperti saat pengguna meninggalkannya.
- Android Debug Bridge (
adb
) adalah alat command line yang memungkinkan Anda mengirimkan petunjuk ke emulator dan perangkat yang terhubung ke komputer Anda. Anda dapat menggunakanadb
untuk menyimulasikan penonaktifan proses di aplikasi Anda. - Saat Android mematikan proses aplikasi Anda, metode siklus proses
onDestroy()
tidak dipanggil. Aplikasi berhenti begitu saja.
Mempertahankan status aktivitas dan fragmen
- Saat aplikasi Anda berpindah ke latar belakang, tepat setelah
onStop()
dipanggil, data aplikasi akan disimpan ke paket. Beberapa data aplikasi, seperti kontenEditText
, akan otomatis disimpan untuk Anda. - Paket tersebut adalah instance
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 denganput
, sepertiputInt()
. - Anda bisa mendapatkan kembali data dari paket dalam metode
onRestoreInstanceState()
, atau yang lebih umum dionCreate()
. MetodeonCreate()
memiliki parametersavedInstanceState
penyimpanan paket. - Jika variabel
savedInstanceState
berisinull
, 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 denganget
, sepertigetInt()
.
Perubahan konfigurasi
- Perubahan konfigurasi terjadi saat status perangkat berubah secara drastis sehingga cara termudah bagi sistem untuk menyelesaikan perubahan adalah dengan menonaktifkan 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 proses.
- 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()
.
Kursus Udacity:
Dokumentasi developer Android:
- Aktivitas (Panduan API)
Activity
(Referensi API)- Memahami Siklus Proses Aktivitas
- Menangani Siklus Proses dengan Komponen Berbasis Siklus Proses
LifecycleOwner
Lifecycle
LifecycleObserver
onSaveInstanceState()
- Menangani perubahan konfigurasi
- Menyimpan Status UI
Lainnya:
- Timber (GitHub)
Bagian ini mencantumkan kemungkinan tugas pekerjaan rumah untuk siswa yang mengerjakan codelab ini sebagai bagian dari kursus yang dipimpin oleh instruktur. Instruktur menentukan hal berikut:
- Memberikan pekerjaan rumah jika diperlukan.
- Memberi tahu siswa cara mengirimkan tugas pekerjaan rumah.
- Memberi nilai tugas pekerjaan rumah.
Instruktur bisa menggunakan saran ini sesuai kebutuhan, dan bebas menugaskan pekerjaan rumah lain yang dirasa cocok.
Jika Anda menyelesaikan codelab ini sendiri, gunakan tugas pekerjaan rumah ini untuk menguji pengetahuan Anda.
Mengubah aplikasi
Buka aplikasi DiceRoller dari Pelajaran 1. (Anda dapat mendownload aplikasi di sini jika belum memilikinya.) Kompilasi dan jalankan aplikasi, lalu perhatikan bahwa jika Anda memutar perangkat, nilai dadu saat ini akan hilang. Terapkan onSaveInstanceState()
untuk mempertahankan nilai tersebut dalam paket, dan pulihkan nilai tersebut di onCreate()
.
Jawab pertanyaan-pertanyaan berikut
Pertanyaan 1
Aplikasi Anda berisi simulasi fisik yang memerlukan komputasi berat untuk ditampilkan. Kemudian, pengguna menerima panggilan telepon. Manakah di antara pilihan berikut yang benar?
- Selama panggilan telepon, Anda harus meneruskan komputasi posisi objek pada simulasi fisik.
- Selama panggilan telepon, Anda harus menghentikan komputasi posisi objek pada simulasi fisik.
Pertanyaan 2
Metode siklus proses mana yang harus Anda ganti untuk menjeda simulasi saat aplikasi tidak ada di layar?
onDestroy()
onStop()
onPause()
onSaveInstanceState()
Pertanyaan 3
Untuk membuat class berbasis siklus proses melalui library siklus proses Android, antarmuka mana yang harus diterapkan oleh class tersebut?
Lifecycle
LifecycleOwner
Lifecycle.Event
LifecycleObserver
Pertanyaan 4
Dalam kondisi apakah metode onCreate()
di aktivitas Anda menerima Bundle
dengan data di dalamnya (yaitu, Bundle
bukan null
)? Mungkin ada lebih dari satu jawaban yang berlaku.
- Aktivitas dimulai ulang setelah perangkat diputar.
- Aktivitas dimulai dari awal.
- Aktivitas dilanjutkan setelah kembali dari latar belakang.
- Perangkat dimulai ulang.
Mulai pelajaran berikutnya:
Untuk link ke codelab lain dalam kursus ini, lihat halaman landing codelab Dasar-Dasar Android Kotlin.