【问题标题】:Viewmodel crash after on onactivityresult, Can not perform this action after onSaveInstanceStateonactivityresult 后 Viewmodel 崩溃,onSaveInstanceState 后无法执行此操作
【发布时间】:2021-11-30 15:29:33
【问题描述】:

我正在尝试一个简单的流程,从我的活动我打开文件选择器然后到 viewmodel,这给了我以下崩溃:

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState

这里是造成这个崩溃的代码:

    private val mainViewModel: MainViewModel by viewModels()

    private var activityResultLaunch = registerForActivityResult(StartActivityForResult()) { result ->
        val fileUri = result.data?.data ?: return@registerForActivityResult

        val stream = contentResolver.openInputStream(fileUri) ?: return@registerForActivityResult

        uploadFiles(stream)
    }

    private fun uploadFiles(stream: InputStream) {
        lifecycleScope.launchWhenStarted {
            mainViewModel.uploadFiles(
                stream = stream
            ).asLiveData().observe(this@MainActivity, {
                handleFileUploadStatus(it)
            })
        }
    }

@HiltViewModel
class MainViewModel @Inject constructor(
    private val filesRepository: FilesRepository
) : ViewModel() {

    suspend fun uploadFiles(stream: InputStream): Flow<UploadStatusUI> {
        return filesRepository.uploadFiles(listOf(stream))
    }
}

经过一番研究,我在 Google 的问题跟踪器 here 上发现了这个问题,在 Firefox 的 github here 上发现了另一个问题,但没有任何效果。显然这个问题在生命周期 2.3.1 中得到了解决,但我仍然面临它。

这是我的版本:

“androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0”

“androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.0”

提前致谢!

编辑:崩溃堆栈跟踪here

【问题讨论】:

  • 哪一行导致崩溃?你能发表超过 1 句例外吗?
  • @Pawel 我在原始帖子中添加了堆栈跟踪,但崩溃是这样的:mainViewModel.uploadFiles

标签: android kotlin android-lifecycle android-viewmodel


【解决方案1】:

根据您链接到的问题,其他人继续遇到同样的问题,所以该库中可能存在错误。也许尝试解决方法。而不是在活动中完成所有工作:

private fun uploadFiles(stream: InputStream) {
    lifecycleScope.launchWhenStarted {
        mainViewModel.uploadFiles(
            stream = stream
        ).asLiveData().observe(this@MainActivity, {
            handleFileUploadStatus(it)
        })
    }
}

分手:

首先,VM 中的实时数据对象:

private val _uploadStatusLiveData = MutableLiveData<UploadStatusUI>()
val uploadStatusLiveData: LiveData<UploadStatusUI> get() = _uploadStatusUI

接下来改变你的虚拟机挂起函数来启动协程:

// Not suspend, no return type - instead collect repo flow and pass to live data
fun uploadFiles(stream: InputStream) {
    viewModelScope.launch(Dispatchers.IO) {
        filesRepository.uploadFiles(listOf(stream)).collect {
            _uploadStatusLiveData.postValue(it)
        }
    }   
}

最后观察activity的变化:

fun onCreate(...) {
    viewModel.uploadStatusLiveData.observe(this) {
        handleUploadStatus(it)
    }
}

并手动启动进程:

fun onStart(...) {
    viewModel.uploadFiles(stream)
}

【讨论】:

  • 不幸的是,这也不起作用,使用 onActivityResult 中的视图模型时会出现问题,但您的回答让我想到了“hacky”修复。
猜你喜欢
  • 2019-05-30
  • 1970-01-01
  • 2012-08-19
  • 2014-10-18
  • 2014-03-05
  • 2017-06-21
  • 1970-01-01
  • 2015-12-23
相关资源
最近更新 更多