lateinit 属性 选择文件资源管理器后未初始化
lateinit property not initialized after pick file explorer
我有一个 activity 让用户 select 从资源管理器中获取文件,在 onActivityResult()
中检索结果并将结果保存在一个名为 Property
[=20 的对象中=]
我有一个如下的 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
应该足够了。
在你的 Activity 中,当它被销毁时首先存储它(我假设你的 Property
class 是 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 }
}
}
}
}
}
}
我有一个 activity 让用户 select 从资源管理器中获取文件,在 onActivityResult()
中检索结果并将结果保存在一个名为 Property
[=20 的对象中=]
我有一个如下的 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
应该足够了。
在你的 Activity 中,当它被销毁时首先存储它(我假设你的 Property
class 是 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 }
}
}
}
}
}
}