问题描述
viewmodel:
class Myviewmodel: viewmodel() {
private var data: Article? = null
// a suspend function actually behaviors as blocking call with withContext
suspend fun getDataByUUID(uuid: String) : Data {
return data ?: withContext(viewmodelScope.coroutineContext + dispatchers.IO) {
(Repository.getDataByUUID(uuid)
.also { data = it }
}
}
}
在Fragment中,它使用viewLifecycleOwner.lifecycleScope.launch{}
调用viewmodel的暂挂函数getDataByUUID(uuid: String)
fun fetchData() {
myviewmodel?.let {
viewLifecycleOwner.lifecycleScope.launch(dispatchers.Main) {
val data = it.getArticleByUUID(strUUID)
article?.let {
updateUIWithData(it)
}
}
}
}
在Fragment中,它具有viewLifecycleOwner.lifecycleScope.launch {},
在启动{}中,它将等待viewmodel的getArticleByUUID()
和do update ui返回的数据。
它可以工作,但是对协程的范围和工作取消有疑问。
此处的片段中有viewLifecycleOwner.lifecycleScop
。并在viewmodel中具有viewmodelScope
。
viewmodel的寿命可能更长(如果进行配置(即更改方向),并且片段可能会被破坏-由os重新创建,但viewmodel未被破坏
在那种情况下,如果碎片被破坏而viewmodel没有被破坏,我想viewLifecycleOwner.lifecycleScope.launch{}
碎片中的作业将被取消,这就是我们想要的,以取消从碎片中启动的作业。 / p>
但是,如果viewmodel仍然存在,我们确实希望viewmodel的getArticleByUUID()
在后台继续运行(因此数据可能会从远程获取并准备在下次使用)。
但是,当Fragment的启动作业被取消时,viewmodel中的suspend fun getDataByUUID()
也将被取消吗?
当viewLifecycleOwner.lifecycleScop.launch{}
启动的片段作业被取消时,是否有一种方法可以让viewmodel中的suspend函数继续而不被取消?
解决方法
但是,当Fragment的启动作业被取消时,ViewModel中的悬挂乐趣getDataByUUID()也将被取消吗?
只要在视图模型中继续使用viewmodelscope,只有在销毁视图模型后,才会取消视图模型上的作业。
package sammysrentalprice;
import javax.swing.JOptionPane;
public class SammysRentalPrice
{
public static void main(String[] args)
{
final int RENT_PER_HOUR = 40;
final int RENT_PER_ADDITIONAL_MINUTE = 1;
final int MINUTES_IN_AN_HOUR = 60;
int minutesRented;
int hoursRented;
int additionalMinutes;
int total;
JOptionPane.showMessageDialog(null,"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\n"
+ "SS SS \n"
+ "SS Sammy's makes it fun in the sun. SS \n"
+ "SS SS \n"
+ "SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS\n");
}
}
Example of what we should use (This was the lab before the one we are on)
package chap2.carlyseventprice;
import javax.swing.JOptionPane;
public class Chap2CarlysEventPrice
{
public static void main(String[] args)
{
final int PRICE_PER_PERSON = 35;
final int LARGE_EVENT = 50;
String strNumOfGuests;
int numOfGuests;
int totalPrice;
strNumOfGuests = JOptionPane.showInputDialog(null,"Enter the number of guests","Guest Entry",JOptionPane.INFORMATION_MESSAGE);
numOfGuests = Integer.parseInt(strNumOfGuests);
totalPrice = numOfGuests * PRICE_PER_PERSON;
JOptionPane.showMessageDialog(null,"*****************************************************\n"
+ "* Carly's makes the food that makes it a party! *\n"
+ "*****************************************************");
JOptionPane.showMessageDialog(null,"Number Of Guests: " + numOfGuests
+ "\nPrice per Guest: " + PRICE_PER_PERSON
+"\nTotal Price: $" + totalPrice
+ "\nLarge event? " + (numOfGuests >= 50));
}
如果每当破坏片段或取消片段中的作业时都删除 viewModelScope.coroutineContext ,您的 getDataByUUID 将被取消。
如果需要,您可以轻松地自己进行测试。您可以像这样延迟创建for:
withContext(viewModelScope.coroutineContext + Dispatchers.IO)