Topik wawancara representatif

Bagaimana cara aplikasi Android bermigrasi ke Predictive Back?

UmumSulit
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Sebuah aplikasi Android masih mengintersepsi tombol kembali dengan onBackPressed atau KeyEvent.KEYCODE_BACK. Rancang migrasi ke Predictive Back, yang mencakup API Compose dan View, pemulihan status saat pembatalan, serta cara menghindari terhapusnya animasi sistem.

Pertanyaan dan cakupan

Anda mengelola aplikasi Android berskala besar dengan Activity, Fragment, dan layar Compose. Mulai Android 15, pengguna dapat melihat pratinjau kembali sistem (system back preview), tetapi layar lawas masih mengintersepsi navigasi kembali dengan onBackPressed atau KeyEvent.KEYCODE_BACK. Akibatnya, animasi hilang, logika konfirmasi muncul pada waktu yang salah, atau status tertinggal setelah gestur dibatalkan. Pewawancara menginginkan migrasi bertahap dan rencana pengujian.

Asumsikan Android 13 dan yang lebih baru harus tetap didukung dan navigation stack tidak dapat ditulis ulang sekaligus. Android merekomendasikan OnBackPressedCallback yang kompatibel dengan versi sebelumnya, atau OnBackInvokedCallback platform saat integrasi sistem langsung diperlukan. Compose menggunakan PredictiveBackHandler saat progres gestur dibutuhkan.

Apa yang dievaluasi pewawancara

  • Apakah Anda memodelkan predictive back sebagai pratinjau yang diikuti oleh komit atau pembatalan, bukan sebagai satu kali klik langsung.
  • Apakah intersepsi lawas beralih ke callback AndroidX yang status aktifnya mengikuti status UI.
  • Apakah Anda memisahkan callback animasi UI dari observer logging atau bisnis sehingga animasi sistem tidak terpakai/tertelan.
  • Apakah Anda menjelaskan urutan callback Compose, pemulihan pembatalan, serta kompatibilitas View/Fragment.
  • Apakah Anda mencakup animasi sistem Android 15, opt-out di tingkat aktivitas, dan pengujian perangkat yang dapat diulang.

Jawaban yang lemah menyatakan "tingkatkan versi AndroidX dan aktifkan flag." Jawaban yang kuat mendefinisikan tanggung jawab callback, pemulihan pembatalan yang idempoten, dan peluncuran aktivitas demi aktivitas.

Klarifikasi sebelum menjawab

  1. Apakah layar menggunakan Fragment/Navigation Component, Compose, atau back stack Activity kustom? Hal tersebut menentukan API migrasi.
  2. Apakah tombol kembali harus mengonfirmasi formulir yang belum disimpan? Callback harus mengikuti status UI sebelum gestur dimulai, bukan memutuskan setelah gestur selesai.
  3. Apakah progres gestur diperlukan untuk animasi kustom? Gunakan BackHandler untuk intersepsi akhir dan PredictiveBackHandler hanya jika progres diperlukan.
  4. Apakah target mencakup Android 15? Animasi sistem dan pengujian berbeda, sementara lapisan kompatibilitas harus mencakup rilis yang lebih lama.
  5. Bisakah aplikasi diluncurkan per Activity atau per layar? Aplikasi besar dapat menggunakan flag enableOnBackInvokedCallback di tingkat aktivitas.

Jawaban-jawaban ini mengubah desain: pertahankan callback sederhana saat progres tidak diperlukan, terapkan pemulihan untuk status formulir, dan migrasikan layar AndroidX sebelum menghapus setiap intersepsi lawas.

Kerangka jawaban 30 detik

"Saya menginventarisasi setiap intersepsi kembali lawas dan mengikat callback ke status UI yang dapat diobservasi. Saya mengganti intersepsi onBackPressed dan KEYCODE_BACK dengan OnBackPressedCallback; saya menggunakan OnBackInvokedCallback hanya untuk integrasi platform langsung, dan PredictiveBackHandler di Compose saat saya membutuhkan progres. Pratinjau hanya mengubah visual yang dapat dikembalikan. Gestur yang dikomit melakukan navigasi atau konfirmasi; gestur yang dibatalkan memulihkan snapshot awal. Callback prioritas default atau overlay dapat menekan animasi sistem, sehingga animasi UI dan logging bisnis menggunakan jalur terpisah. Saya meluncurkan ini per Activity dan mengujinya di Android 13, 14, dan 15."

Solusi langkah demi langkah

1. Modelkan kembali sebagai state machine

Perlakukan gestur sebagai idle → preview(progress) → committed atau idle → preview(progress) → cancelled. Pratinjau hanya memperbarui visual yang dapat dikembalikan. Komit melakukan navigasi, penutupan, atau konfirmasi. Pembatalan memulihkan snapshot. Tidak boleh ada penulisan bisnis yang tidak dapat diubah selama periode saat pengguna masih dapat melepaskan gestur.

2. Migrasikan API intersepsi lawas

Jalur kompatibilitas Android adalah meningkatkan AndroidX Activity dan mendaftarkan OnBackPressedCallback dengan OnBackPressedDispatcher. Berhenti mengintersepsi di Activity.onBackPressed atau KeyEvent.KEYCODE_BACK. Gunakan OnBackInvokedCallback saat integrasi kembali tingkat platform diperlukan. KEYCODE_BACK masih memiliki penggunaan yang didukung, tetapi tidak boleh lagi menjadi titik masuk intersepsi kembali.

kotlin
val confirmCallback = object : OnBackPressedCallback(false) {
    override fun handleOnBackPressed() {
        showDiscardDialog()
    }
}

onBackPressedDispatcher.addCallback(viewLifecycleOwner, confirmCallback)
formState.collect { state ->
    confirmCallback.isEnabled = state.hasUnsavedChanges
}

Status aktif berasal dari status formulir yang dapat diobservasi, bukan pemeriksaan terlambat setelah callback terpicu. Ketika formulir bersih, nonaktifkan callback sehingga sistem atau navigation component menangani navigasi kembali.

3. Tangani progres dan pembatalan di Compose

Gunakan PredictiveBackHandler untuk mengumpulkan BackEventCompat saat layar Compose memerlukan animasi berbasis progres. Pulihkan animasi dan status bertahap saat pengumpulan dibatalkan atau gestur tidak dikomit. Gunakan BackHandler untuk intersepsi akhir tanpa progres agar layar sederhana tidak memuat logika gestur yang tidak perlu.

kotlin
PredictiveBackHandler(enabled = canNavigateBack) { progress ->
    try {
        progress.collect { event -> renderPreview(event.progress) }
        navigateBack()
    } catch (cancelled: CancellationException) {
        restorePreviewState()
    }
}

Callback diproses sebagai tumpukan (stack): callback aktif terakhir yang ditambahkan akan menangani gestur berikutnya. Dalam Compose bersarang, PredictiveBackHandler atau BackHandler terdalam yang menang, jadi hindari callback global yang ambigu.

4. Jangan menelan animasi sistem

Panduan Android menyatakan bahwa OnBackPressedCallback atau OnBackInvokedCallback pada PRIORITY_DEFAULT atau PRIORITY_OVERLAY mencegah animasi sistem prediktif dan membuat aplikasi menangani animasinya sendiri. Callback UI harus mengontrol dialog dan transisi. Logging atau observasi bisnis harus menggunakan jalur observasi non-konsumtif daripada callback prioritas tinggi yang memblokir sistem.

5. Luncurkan per Activity

Setel android:enableOnBackInvokedCallback di tingkat aplikasi atau timpa untuk satu Activity. Aplikasi besar dapat mengaktifkannya untuk Activity yang sudah dimigrasi sementara layar lawas memilih keluar (opt-out) untuk sementara, kemudian menghapus intersepsi lama satu layar demi satu layar. Menonaktifkan flag akan mengabaikan OnBackInvokedCallback, tetapi OnBackPressedCallback AndroidX masih dapat berjalan, jadi uji kedua jalur tersebut secara terpisah.

6. Uji komit, pembatalan, dan batas-batas skenario

Untuk setiap pengujian layar: lepaskan sebelum ambang batas komit; lepaskan setelah ambang batas; formulir kotor dan bersih; callback Fragment/Compose bersarang; kembali dari root Activity ke beranda sistem; serta Android 13, 14, dan 15. Pastikan verifikasi mencakup navigation stack, data formulir, status animasi akhir, dan status callback aktif, bukan hanya tangkapan layar.

Contoh jawaban berkualitas tinggi

"Saya akan memodelkan kembali sebagai state machine yang dapat dibatalkan dan menginventarisasi intersepsi lawas di Activity, Fragment, dan Compose. Migrasi kompatibilitas menggunakan OnBackPressedCallback; OnBackInvokedCallback adalah untuk integrasi platform langsung; PredictiveBackHandler hanya untuk animasi progres Compose. Status aktif callback mengikuti apakah formulir kotor atau tidak. Pratinjau mengubah visual yang dapat dikembalikan, pembatalan memulihkannya, dan komit melakukan navigasi atau konfirmasi.

"Saya akan menghindari callback prioritas default atau overlay yang menelan animasi sistem dan memisahkan animasi UI dari logging. Aplikasi besar meluncurkan enableOnBackInvokedCallback per Activity, menguji Android 13, 14, dan 15 untuk komit dan pembatalan, serta menghapus intersepsi onBackPressed dan KEYCODE_BACK secara bertahap. Pemeriksaan penerimaan memverifikasi navigasi, pemulihan status, urutan callback, dan perilaku kembali ke beranda sistem, bukan hanya satu animasi."

Kesalahan umum

  • Kesalahan: memeriksa status formulir kotor hanya di dalam handleOnBackPressed → Mengapa gagal: pratinjau sudah terjadi dan pembatalan tidak dapat memulihkan dengan benar → Perbaikan: aktifkan atau nonaktifkan callback dari status yang dapat diobservasi.
  • Kesalahan: mendaftarkan callback PRIORITY_OVERLAY global di mana-mana → Mengapa gagal: animasi prediktif sistem tertelan → Perbaikan: konsumsi hanya event UI yang diperlukan dan gunakan observasi non-konsumtif untuk log.
  • Kesalahan: hanya memanggil navigateBack() di Compose → Mengapa gagal: status pratinjau tetap ada setelah pembatalan → Perbaikan: tangkap pembatalan dan pulihkan snapshot.
  • Kesalahan: hanya menguji di perangkat Android 15 → Mengapa gagal: API kompatibilitas dan perilaku versi lama tetap tidak terverifikasi → Perbaikan: cakup Android 13, 14, 15 dan flag tingkat aktivitas.

Pertanyaan lanjutan dan tanggapan

Apa yang harus terjadi pada data formulir saat pengguna melepaskan gestur di tengah jalan?

Pratinjau hanya mengubah visual sementara. Pertahankan model formulir dan data yang disimpan tidak berubah, lalu pulihkan snapshot visual saat gestur dibatalkan. Jangan tampilkan dialog simpan/buang untuk gestur yang tidak pernah dikomit.

Mengapa tidak menggunakan satu callback global untuk setiap layar?

Prioritas callback tergantung pada urutan tumpukan dan status aktif. Callback global dapat menyembunyikan logika Fragment, Navigation, atau Compose dan tidak dapat mengetahui status belum tersimpan dari layar saat ini. Callback dengan tanggung jawab tunggal di tingkat layar lebih mudah diverifikasi.

Bagaimana cara mencatat log tombol kembali tanpa mengorbankan animasi sistem?

Jangan gunakan callback default atau overlay yang bersifat konsumtif untuk logging. Untuk keluar dari root Activity, gunakan observer navigasi sistem atau sinyal siklus proses (lifecycle); jaga agar callback UI bertanggung jawab atas perilaku UI.

Bagaimana aplikasi besar dengan banyak Activity meluncurkan fitur ini?

Mulailah dengan pengaturan aplikasi yang konservatif, lalu timpa enableOnBackInvokedCallback=true pada Activity yang telah dimigrasi. Perluas hanya setelah setiap Activity lolos pengujian komit, pembatalan, callback bersarang, dan versi lama.

API Compose mana yang tepat jika hanya navigasi kembali akhir yang dibutuhkan?

Gunakan BackHandler. API ini mengekspresikan intersepsi akhir dengan semantik pembatalan yang lebih sederhana. Gunakan PredictiveBackHandler hanya saat BackEventCompat.progress menggerakkan animasi interaktif.

Referensi

  • Android Developers: Menambahkan dukungan untuk gestur predictive back.
  • Android Developers: Desain predictive back.
  • Android Developers: Tentang Predictive back untuk Jetpack Compose.

Sumber publik

Pertanyaan terkait