Android 如何避免在任务完成之前导航到下一个?
我在其中一个片段上有以下Android 如何避免在任务完成之前导航到下一个?,android,kotlin,task,Android,Kotlin,Task,我在其中一个片段上有以下clickListener binding.btnCamera.setOnClickListener { val photo = takePhoto() val prediction = MachineLearning().predict(photo) val action = FirstFragmentDirections.actionFirstToSecond(prediction)
clickListener
binding.btnCamera.setOnClickListener {
val photo = takePhoto()
val prediction = MachineLearning().predict(photo)
val action = FirstFragmentDirections.actionFirstToSecond(prediction)
findNavController().navigate(action)
}
MachinLearing.ktpredict()
函数如下所示,其中包含异步执行的任务
fun predict(photo: Bitmap): Boolean {
val conditions = CustomModelDownloadConditions.Builder()
.requireWifi()
.build()
FirebaseModelDownloader.getInstance()
.getModel(modelName, DownloadType.LOCAL_MODEL_UPDATE_IN_BACKGROUND, conditions)
.addOnSuccessListener { customModel ->
...
}
.addOnFailureListener{
...
}
...
}
我想停止导航到下一个片段,直到predict()
中的任务完成
由于任务的异步性质
<代码>任务
在片段导航之前完成的可能性较小。如果发生了片段导航,则将在当前片段中调用onDestroy()
,从而导致MachineLearning
对象被垃圾收集,因此任务
完全不会完成
那么我怎么能在片段导航之前等待任务完成呢?方法
addOnCompleteListener
和addOnFailureListener
都是回调。这意味着它是异步的,因此无论方法predict
返回什么,它都可能在触发这些方法之前或之后发生。有两个选项:添加另一个回调或将其转换为挂起
回拨:
fun predict(photo: Bitmap, predictionDelegate: (Boolean) -> Unit) {
//...
addOnCompleteListener { model ->
//do your thing and then call the callback
predictionDelegate.invoke(yourCalculatedBoolean)
}
.addOnFailureListener...//do the same
}
然后我要说:
MachineLearning().predict(photo) { prediction ->
val action = FirstFragmentDirections.actionFirstToSecond(prediction)
findNavController().navigate(action)
}
另一种选择是将其挂起:
suspend fun predict(): Boolean() {
val deferred = CompletableDeferred<Boolean()
//your thing
enter code here
.addOnSuccessListener { model ->
//do your thing and then update the defferred
deferred.complete(yourCalculatedBoolean)
}
.addOnFailureListener...//do the same
return deferred.await()
}
我假设您由于绑定而处于
片段
或活动
,因此您应该具有生命周期范围
方法addOnCompleteListener
和addOnFailureListener
都是回调。这意味着它是异步的,因此无论方法predict
返回什么,它都可能在触发这些方法之前或之后发生。有两个选项:添加另一个回调或将其转换为挂起
回拨:
fun predict(photo: Bitmap, predictionDelegate: (Boolean) -> Unit) {
//...
addOnCompleteListener { model ->
//do your thing and then call the callback
predictionDelegate.invoke(yourCalculatedBoolean)
}
.addOnFailureListener...//do the same
}
然后我要说:
MachineLearning().predict(photo) { prediction ->
val action = FirstFragmentDirections.actionFirstToSecond(prediction)
findNavController().navigate(action)
}
另一种选择是将其挂起:
suspend fun predict(): Boolean() {
val deferred = CompletableDeferred<Boolean()
//your thing
enter code here
.addOnSuccessListener { model ->
//do your thing and then update the defferred
deferred.complete(yourCalculatedBoolean)
}
.addOnFailureListener...//do the same
return deferred.await()
}
我假设由于绑定,您处于
片段
或活动
,因此您应该具有lifecycleScope
基本上,您应该将回调传递到predict
,当工作完成时触发。但是,当您使用Kotlin时,我建议您研究挂起函数。@user158我的最佳猜测是,因为人们看到了数百个异步问题,这些问题不是问题,而是缺乏对异步编程工作原理的理解。检查我的答案,这可能会对你有所帮助。@user158为什么混合主题是一个有效的借口?@user158你不知道主题a,但你提到主题B,提到主题B并不能弥补事先不知道,你应该将回调传递到predict
,当工作完成时触发。但是,当您使用Kotlin时,我建议您研究挂起函数。@user158我的最佳猜测是,因为人们看到了数百个异步问题,这些问题不是问题,而是缺乏对异步编程工作原理的理解。检查我的答案,这可能会对你有所帮助。@user158为什么混合主题会是一个有效的借口?@user158你不知道主题a,但你提到主题B,提到主题B并不能弥补你不知道A@user158看一看again@user158再看看