如何避免在任务完成之前导航到下一个?
How to avoid navigating to next until Task is complete?
我关注了其中一个片段clickListener
binding.btnCamera.setOnClickListener {
val photo = takePhoto()
val prediction = MachineLearning().predict(photo)
val action = FirstFragmentDirections.actionFirstToSecond(prediction)
findNavController().navigate(action)
}
MachinLearing.kt predict()
函数如下所示,其中包含一个异步执行的任务。
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()
内的 Task
完成。
由于 Task
的异步性质。 Task
在片段导航之前不太可能完成。如果发生片段导航,则 onDestroy()
将在当前片段中调用,导致 MachineLearning
对象被垃圾收集,因此 Task
完成根本不会发生。
那么我怎么能在片段导航之前等待任务完成呢?
方法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.launch {
val prediction = MachineLearning().predict(photo)
val action = FirstFragmentDirections.actionFirstToSecond(prediction)
findNavController().navigate(action)
}
由于绑定,我假设您处于 Fragment
或 Activity
,因此您应该 lifecycleScope
.
我关注了其中一个片段clickListener
binding.btnCamera.setOnClickListener {
val photo = takePhoto()
val prediction = MachineLearning().predict(photo)
val action = FirstFragmentDirections.actionFirstToSecond(prediction)
findNavController().navigate(action)
}
MachinLearing.kt predict()
函数如下所示,其中包含一个异步执行的任务。
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()
内的 Task
完成。
由于 Task
的异步性质。 Task
在片段导航之前不太可能完成。如果发生片段导航,则 onDestroy()
将在当前片段中调用,导致 MachineLearning
对象被垃圾收集,因此 Task
完成根本不会发生。
那么我怎么能在片段导航之前等待任务完成呢?
方法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.launch {
val prediction = MachineLearning().predict(photo)
val action = FirstFragmentDirections.actionFirstToSecond(prediction)
findNavController().navigate(action)
}
由于绑定,我假设您处于 Fragment
或 Activity
,因此您应该 lifecycleScope
.