【发布时间】:2021-11-04 02:04:41
【问题描述】:
我是协程的新手,我正在尝试从Dispatchers.IO 的内部存储中加载几个文件以及其他一些东西。所以我开始一个协程,然后调用几个挂起函数,每个函数都使用withContext 来读取它的文件。但是在第一个函数中,withContext 运行它的代码并且永远不会返回,所以协程的其余部分永远不会运行。 withContext 或 Dispatchers.IO 有什么特别之处吗?
class MainViewModel(
application: Application
) : AndroidViewModel(application) {
private val liveSettings: MutableLiveData<Settings>
suspend fun loadSettings(context: Context): Settings = withContext(Dispatchers.IO) {
var settings: Settings
try {
context.openFileInput(FileManager.settingsDir).use { stream ->
val jsonData = stream.readBytes().decodeToString()
settings = Json.decodeFromString(Settings.serializer(), jsonData)
}
} catch (e: IOException){
settings = Settings(mutableListOf(), mutableListOf())
}
Log.d("MainViewModel", "Loading Settings") // this line is run
settings
}
init{
Log.i("MainViewModel", "ViewModel Constructed")
liveSettings = MutableLiveData()
viewModelScope.launch {
Log.d("MainViewModel", "constructor coroutine started")
liveSettings.value = loadSettings(getApplication())
Log.d("MainViewModel", "Hello") // this line is not run
// other stuff...
}
}
}
我希望输出像
ViewModel Constructed
constructor coroutine started
Loading Settings
Hello
但输出是
ViewModel Constructed
constructor coroutine started
Loading Settings
【问题讨论】:
-
在您分享的代码中,当您删除
withContext函数调用时,是否会打印“Hello”? -
如果我将
viewModelScope.launch {更改为viewModelScope.launch (Dispatchers.Default) {并且我将我的设置变量移到MutableLiveData对象之外(显然MutableLiveDatas 不喜欢除了主线程。但我仍然不明白这对内部withContext有什么影响。普通的.launch{是否使协程在主线程上运行? -
我看不出你发布的代码有什么问题。我想知道您是否评论了某些内容或删除了您认为不相关但实际上相关的内容。
viewModelScope.launch默认使用主线程,是的。如上所示,您对withContext的使用是正确的。其他地方可能有一些代码阻塞了主线程。
标签: android android-studio kotlin kotlin-coroutines