我是协同程序的新手,我正在尝试从Dispatchers.IO
上的内部存储加载几个文件以及其他一些东西。因此,我启动了一个协程,然后调用几个suspend函数,每个函数都使用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
我的猜测是应用程序正在崩溃,但你没有意识到。请仔细检查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...
}