Свойство lateinit не инициализируется после выбора проводника - PullRequest
0 голосов
/ 29 февраля 2020

У меня есть действие, которое позволяет пользователю выбрать файл из проводника, получить результат в 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
                    }
                }
            }
        }
    }
}

Проблема в том, что в некоторых случаях я получал следующие сообщения об ошибках аварийного отключения:

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

Я пробовал это много раз, и я получал эти ошибки только несколько раз. (не знает, что вызвать это). Но некоторые пользователи жалуются, что приложение всегда зависало после выбора файлов из проводника. Я проверил аварийный сбой, и сообщение, как упомянуто выше.

Я пытался отладить, используя точку останова до startActivityForResult(). Переменная uploadProperties уже инициализирована, и значение верное. Но после выбора файла из проводника в некоторых случаях приложение по-прежнему зависало с UninitializedPropertyAccessException.

Есть идеи, что вызвало эту ошибку и как ее исправить?

1 Ответ

1 голос
/ 29 февраля 2020

Вам нужно разобраться со случаем, когда процесс вашего приложения разрушается, чтобы освободить память. В вашем случае хранения 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 }
                    }
                }
            }
        }
    }
}
...