Burada düşünülmesi gereken birkaç şey var, çünkü bu kedinin derisini almanın pek çok yolu var. Her ne kadar cevapların hepsi seçilmiş ve seçilmiş olsa da. Ben sadece "çoğunluk seçilen basit cevap" nedeniyle yanlış yönde gitmesini önlemek için bu uygun kodlama yönergeleri ile yeniden ele alınması önemlidir düşünüyorum.
İlk olarak, bu iş parçacığında genel olarak seçilen kazanan cevap olan basit Post Gecikmeli yanıtı tartışalım.
Dikkate alınması gereken birkaç şey. Post gecikmeden sonra bellek sızıntıları, ölü nesneler, gitmiş olan yaşam döngüleri ve daha fazlası ile karşılaşabilirsiniz. Bu yüzden düzgün bir şekilde kullanmak da önemlidir. Bunu birkaç şekilde yapabilirsiniz.
Modern gelişim uğruna KOTLIN'de tedarik edeceğim
Geri aramada UI iş parçacığını kullanmanın ve geri aramanıza bastığınızda etkinliğinizin hala canlı ve iyi olduğunu onaylamanın basit bir örneği.
Handler(Looper.getMainLooper()).postDelayed({
if(activity != null && activity?.isFinishing == false){
txtNewInfo.visibility = View.GONE
}
}, NEW_INFO_SHOW_TIMEOUT_MS)
Ancak, etkinlik hala ortadan kalktığında geri aramanıza ulaşmak için hiçbir neden olmadığından bu hala mükemmel değildir. bu nedenle daha iyi bir yol, bir referans tutmak ve bunun geri aramalarını kaldırmak olabilir.
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)
}
}
ve elbette onPause'da temizlemeyi halledin, böylece geri aramaya basmaz.
override fun onPause() {
super.onPause()
mHandler.removeCallbacks(null)
}
Şimdi bariz konuştuk, modern coroutines ve kotlin ile daha temiz bir seçenek hakkında konuşalım :). Bunları henüz kullanmıyorsanız, gerçekten kaçırıyorsunuz demektir.
fun doActionAfterDelay()
launch(UI) {
delay(MS_TO_DELAY)
actionToTake()
}
}
veya bu yöntemde her zaman bir UI lansmanı yapmak istiyorsanız şunları yapabilirsiniz:
fun doActionAfterDelay() = launch(UI){
delay(MS_TO_DELAY)
actionToTake()
}
Tabii ki PostDelayed gibi, gecikme çağrısından sonra etkinlik kontrollerini yapabilmeniz veya diğer rota gibi onPause'da iptal edebilmeniz için iptal işlemini yaptığınızdan emin olmanız gerekir.
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}")
}
}
}
}
// temizleme işlemlerini gerçekleştirme
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
}
}
Lansmanı (UI) yöntem imzasına koyarsanız, iş çağrı kod satırına atanabilir.
öyleyse, hikayenin ahlaki gecikmiş eylemlerinizle güvende olmak, geri aramalarınızı kaldırdığınızdan veya işlerinizi iptal ettiğinizden emin olun ve elbette gecikme geri aramanızdaki öğelere dokunmak için doğru yaşam döngüsüne sahip olduğunuzu doğrulayın. Coroutines ayrıca iptal edilebilir eylemler sunar.
Ayrıca, genellikle coroutines ile birlikte gelebilecek çeşitli istisnaları ele almanız gerektiğini belirtmek gerekir. Örneğin, bir iptal, bir istisna, bir zaman aşımı, ne kullanmaya karar verirseniz verin. İşte coroutines kullanmaya gerçekten karar verirseniz daha gelişmiş bir örnek.
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}")
}
}