withContext(Dispatchers.IO)在运行后无限阻塞



我是协同程序的新手,我正在尝试从Dispatchers.IO上的内部存储加载几个文件以及其他一些东西。因此,我启动了一个协程,然后调用几个suspend函数,每个函数都使用withContext读取其文件。但是在第一个函数中,withContext运行它的代码并且永远不会返回,所以协程的其余部分永远不会运行。withContextDispatchers.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

我的猜测是应用程序正在崩溃,但你没有意识到。请仔细检查logcat。不能在主线程之外设置实时数据值。您应该使用postValue

viewModelScope.launch {
Log.d("MainViewModel", "constructor coroutine started")
// This is launched on an non UI thread - use postValue
liveSettings.postValue(loadSettings(getApplication()))
Log.d("MainViewModel", "Hello")            // this line is not run
// other stuff...
}

最新更新