UnitialisedPropertyAccessException даже после того, как lateinit var был инициализирован? - PullRequest
0 голосов
/ 22 января 2020

У меня проблемы с некоторым кодом Kotlin, с которым я раньше не сталкивался.

В одном упражнении я объявляю переменную поздней инициализации:

lateinit var currentUser : User

И позже инициализировать это. Я знаю, что он инициализирован, потому что я использовал метод isInitialized для двойной проверки после его инициализации:

private fun instantiateUser(name : String?, email : String?, flatId : String?) {
    currentUser = User(name, email, flatId)
    if(::currentUser.isInitialized) {
        Toast.makeText(this@HomeActivity, "Initialised", Toast.LENGTH_SHORT).show()
    } else {
        Toast.makeText(this@HomeActivity, "Not initialised", Toast.LENGTH_SHORT).show()
    }
}

Я получил ожидаемый результат, поэтому я знаю, что currentUser инициализирован. Однако при последующем вызове из действия, которое запускается сразу после этого, я получаю исключение UnitializedPropertyAccessEx в этой строке:

var currentUser = HomeActivity().currentUser

Вот класс User, если он имеет отношение:

@IgnoreExtraProperties
data class User(
    var name: String? = "",
    var email: String? = "",
    var flat: String? = ""
)

Любые предложения о том, что может быть причиной этого, будут высоко оценены.

Ответы [ 3 ]

1 голос
/ 22 января 2020

Чтобы немного расширить ответ zsmb13 :

На самом деле вы не должны создавать экземпляры Activity, это делается системой. Если вы хотите передать объект User в другое действие, самый простой способ - использовать встроенные функции Kotlin и разделить пользователя так, чтобы он выглядел следующим образом:

@Parcelize
@IgnoreExtraProperties
data class User(
        var name: String? = "",
        var email: String? = "",
        var flat: String? = ""
) : Parcelable

Чтобы передать его другое задание ( это относится к HomeActivity):

val i = Intent(this, SecondActivity::class.java).putExtra("YOUR_KEY", currentUser)
startActivity(i)

и получите его во втором задании, например, в onCreate():

val user: User? = intent?.getParcelableExtra("YOUR_KEY")
1 голос
/ 22 января 2020

Используя HomeActivity().currentUser, на самом деле вы создаете другой экземпляр HomeActivity, где currentUser не инициализируется. Проверьте следующие параметры:

Опция - 1: Пройдите через intent

Intent(this, OtherActivity::class.java).apply {
    putExtra("CURRENT_USER", currentUser)
    startActivity(this)
}

Для этого вам необходимо сделать User либо Сериализуемым или Parcelable

@Parcelize
@IgnoreExtraProperties
data class User(
    var name: String? = "",
    var email: String? = "",
    var flat: String? = ""
) : Parcelable

ИЛИ

@IgnoreExtraProperties
data class User(
    var name: String? = "",
    var email: String? = "",
    var flat: String? = ""
) : Serializable

Опция - 2: Вы можете сделать свой currentUser stati c, используя companion object

companion object {
    lateinit var currentUser : User
}

А затем позвоните, как показано ниже, из другой деятельности

HomeActivity.currentUser
0 голосов
/ 22 января 2020

Запись HomeActivity() является вызовом конструктора этой Деятельности, и создаст его новый экземпляр. У этого нового экземпляра еще не будет установлено свойство currentUser. Вы никогда не должны создавать экземпляры Activity вручную, но вместо этого позвольте системе сделать это, используя Intents .

Если вы хотите поделиться currentUser, хранящимся в вашем HomeActivity, вы можете передать ссылку на ваш существующий HomeActivity другим классам. Если вы хотите обмениваться данными между операциями, вы можете передать их через Intent дополнительные данные, либо сохранив их в базе данных, а затем прочитав их оттуда, либо разделив ViewModel между двумя операциями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...