在pick文件资源管理器之后,lateinit属性未初始化



我有一个活动,让用户从资源管理器中选择文件,在onActivityResult()中检索结果,并将结果保存在一个名为Property的对象中

我有一个lateinit变量如下:

lateinit var uploadProperties: Property

打开资源管理器的代码(权限已授予(:

fun openExplorer(property: Property) {
uploadProperties = property
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = Constants.ALL_FILE
intent.addCategory(Intent.CATEGORY_OPENABLE)
startActivityForResult(
Intent.createChooser(intent, getString(R.string.select_file)),
REQ_FILE
)
}

然后是onActivityResult((,我将数据转换为base64并将其分配给属性

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQ_FILE -> {
data?.let {
val base64 = data.toBase64()
uploadProperties.let {
value = base64
}
}
}
}
}
}

问题是,在某些情况下,我收到了以下关于crashlytics的错误报告:

Caused by kotlin.UninitializedPropertyAccessException
lateinit property uploadProperties has not been initialized

我尝试了很多次,但只有几次出现错误(不知道是什么触发了这个(。但一些用户抱怨,该应用程序总是在从资源管理器中选择文件后崩溃。我查看了crashlytics,消息如上所述。

startActivityForResult()之前,我尝试过使用断点进行调试。变量uploadProperties已初始化,并且值正确。但在从资源管理器中选择文件后,在某些情况下,应用程序仍然会因UninitializedPropertyAccessException而崩溃。

知道是什么导致了这个错误以及如何修复这个错误吗?

您需要处理应用程序进程被破坏的情况以释放内存。在您的情况下,存储uploadProperties应该足够了。

在您的"活动"中,首先在它被销毁时存储它(我假设您的Property类是Parcelable,如果不写任何您需要的东西,以便以后能够恢复它(:

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
// ( ... your save instance states if any)
// store upload properties if they were set up
if(::uploadProperties.isInitialized)
outState.putParcelable("uploadProperties", uploadProperties)
}

然后将其恢复到onCreate:中的某个位置

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// (...)
if(savedInstanceState?.containsKey("uploadProperties") == true){
uploadProperties = savedInstanceState.getParcelable("uploadProperties")!!
}
// (...)
}

现在更改您的结果回调,使其延迟到您的属性恢复后:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
when (requestCode) {
REQ_FILE -> {
data?.let {
val base64 = data.toBase64()
// delay using androidx.lifecycle
lifecycleScope.launchWhenCreated {
uploadProperties.let { it.value = base64 }
}
}
}
}
}
}

最新更新