Jadi ada beberapa hal yang perlu dipertimbangkan di sini karena ada begitu banyak cara untuk menguliti kucing ini. Meskipun semua jawaban sudah diberikan dipilih dan dipilih. Saya pikir ini penting bahwa ini akan ditinjau kembali dengan pedoman pengkodean yang tepat untuk menghindari orang salah arah hanya karena "jawaban sederhana yang dipilih mayoritas".
Jadi pertama-tama mari kita bahas jawaban sederhana Post Delayed yaitu jawaban yang dipilih secara keseluruhan di utas ini.
Beberapa hal yang perlu dipertimbangkan. Setelah jeda posting, Anda dapat menemukan kebocoran memori, benda mati, siklus hidup yang telah hilang, dan banyak lagi. Jadi penanganannya dengan benar juga penting. Anda dapat melakukan ini dalam beberapa cara.
Demi perkembangan modern, saya akan memasok di KOTLIN
Berikut adalah contoh sederhana menggunakan utas UI pada panggilan balik dan mengonfirmasi bahwa aktivitas Anda masih hidup dan baik ketika Anda menekan panggilan balik Anda.
Handler(Looper.getMainLooper()).postDelayed({
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.GONE
}
}, NEW_INFO_SHOW_TIMEOUT_MS)
Namun, ini masih belum sempurna karena tidak ada alasan untuk menelepon balik Anda jika aktivitas telah hilang. jadi cara yang lebih baik adalah menyimpan referensi dan menghapus callbacknya seperti ini.
private fun showFacebookStylePlus1NewsFeedOnPushReceived(){
A35Log.v(TAG, "showFacebookStylePlus1NewsFeedOnPushReceived")
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.VISIBLE
mHandler.postDelayed({
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.GONE
}
}, NEW_INFO_SHOW_TIMEOUT_MS)
}
}
dan tentu saja menangani pembersihan pada onPause sehingga tidak menekan callback.
override fun onPause() {
super.onPause()
mHandler.removeCallbacks(null)
}
Sekarang kita telah membahas yang jelas, mari kita bicara tentang opsi yang lebih bersih dengan coroutine dan kotlin modern :). Jika Anda belum menggunakannya, Anda benar-benar ketinggalan.
fun doActionAfterDelay()
launch(UI) {
delay(MS_TO_DELAY)
actionToTake()
}
}
atau jika Anda ingin selalu melakukan peluncuran UI pada metode itu, Anda cukup melakukannya:
fun doActionAfterDelay() = launch(UI){
delay(MS_TO_DELAY)
actionToTake()
}
Tentu saja sama seperti PostDelayed Anda harus memastikan Anda menangani pembatalan sehingga Anda dapat melakukan pemeriksaan aktivitas setelah panggilan tunda atau Anda dapat membatalkannya di onPause sama seperti rute lainnya.
var mDelayedJob: Job? = null
fun doActionAfterDelay()
mDelayedJob = launch(UI) {
try {
delay(MS_TO_DELAY)
actionToTake()
}catch(ex: JobCancellationException){
showFancyToast("Delayed Job canceled", true, FancyToast.ERROR, "Delayed Job canceled: ${ex.message}")
}
}
}
}
// menangani pembersihan
override fun onPause() {
super.onPause()
if(mDelayedJob != null && mDelayedJob!!.isActive) {
A35Log.v(mClassTag, "canceling delayed job")
mDelayedJob?.cancel() //this should throw CancelationException in coroutine, you can catch and handle appropriately
}
}
Jika Anda memasukkan peluncuran (UI) ke dalam metode tanda tangan, pekerjaan itu dapat ditetapkan dalam baris kode panggilan.
jadi moral dari cerita ini adalah untuk aman dengan tindakan Anda yang tertunda, pastikan Anda menghapus panggilan balik Anda, atau membatalkan pekerjaan Anda dan tentu saja mengkonfirmasi Anda memiliki siklus hidup yang tepat untuk menyentuh item pada penundaan panggilan balik Anda selesai. Coroutine juga menawarkan tindakan yang dapat dibatalkan.
Juga patut dicatat bahwa Anda biasanya harus menangani berbagai pengecualian yang dapat terjadi pada coroutine. Misalnya, pembatalan, pengecualian, batas waktu, apa pun yang Anda putuskan untuk digunakan. Ini adalah contoh yang lebih maju jika Anda memutuskan untuk benar-benar mulai menggunakan coroutine.
mLoadJob = launch(UI){
try {
//Applies timeout
withTimeout(4000) {
//Moves to background thread
withContext(DefaultDispatcher) {
mDeviceModelList.addArrayList(SSDBHelper.getAllDevices())
}
}
//Continues after async with context above
showFancyToast("Loading complete", true, FancyToast.SUCCESS)
}catch(ex: JobCancellationException){
showFancyToast("Save canceled", true, FancyToast.ERROR, "Save canceled: ${ex.message}")
}catch (ex: TimeoutCancellationException) {
showFancyToast("Timed out saving, please try again or press back", true, FancyToast.ERROR, "Timed out saving to database: ${ex.message}")
}catch(ex: Exception){
showFancyToast("Error saving to database, please try again or press back", true, FancyToast.ERROR, "Error saving to database: ${ex.message}")
}
}