【问题标题】:getting an IllegalStateException while getting a list of custom type from SavedInstanceState从 SavedInstanceState 获取自定义类型列表时获取 IllegalStateException
【发布时间】:2020-06-14 06:11:44
【问题描述】:

我有一个实现 Parcelable 的 Question 类,它充当 myquiz.db 和 dbHelper 类之间的桥梁。我要做的就是在设备旋转后恢复状态。这是 onSaveInstanceState() 中的代码:

override fun onSaveInstanceState(outState: Bundle?, outPersistentState: PersistableBundle?) {
        super.onSaveInstanceState(outState, outPersistentState)
        outState?.putInt(KEY_SCORE, score)
        outState?.putInt(KEY_QUES_COUNT, questionCounter)
        outState?.putBoolean(KEY_ANSWERED, answered)
        outState?.putLong(KEY_MILLIS_LEFT, timeLeftInMillis)
        outState?.putParcelableArrayList(KEY_QUES_LIST, list)
    }

这是我从 savedInstanceState 恢复列表的代码:

if (savedInstanceState == null) {
        val dbHelper = QuizDbHelper(this)
        list = dbHelper.getAllQuestions()
        totalQuestions = list.size
        list.shuffle()
        textDefaultColor = rb1.textColors
        textDefaultColorcd = timer.textColors
        nextQuestion()
    } else {
        **list = savedInstanceState.getParcelableArrayList(KEY_QUES_LIST)**
        totalQuestions = list.size
        score = savedInstanceState.getInt(KEY_SCORE)
        answered = savedInstanceState.getBoolean(KEY_ANSWERED)
        questionCounter = savedInstanceState.getInt(KEY_QUES_COUNT)
        currQuestion = list[questionCounter - 1]
        timeLeftInMillis = savedInstanceState.getLong(KEY_MILLIS_LEFT)

        if (!answered) {
            startTimer()
        } else {
            updateCoundownText()
            correctAnswer()
        }
    }

当我运行应用程序时,我收到此错误:java.lang.IllegalStateException: savedInstanceState.getPa…eArrayList(KEY_QUES_LIST) must not be null else 块中的第一行类型不匹配。此外,当我将鼠标指针悬停在这一行上时,它会显示:

Required:
ArrayList<Question>
Found:
ArrayList<Question!>?

列表声明:private lateinit var list: ArrayList&lt;Question&gt;

问题.class

class Question() : Parcelable {
private lateinit var question: String
private lateinit var option1: String
private lateinit var option2: String
private lateinit var option3: String
private var answerNr = 0

constructor(question: String, option1: String, option2: String, option3: String, answerNr: Int) : this() {
    this.question = question
    this.option1 = option1
    this.option2 = option2
    this.option3 = option3
    this.answerNr = answerNr
}

constructor(parcel: Parcel) : this() {
    parcel.readString()
    parcel.readString()
    parcel.readString()
    parcel.readString()
    parcel.readInt()
}


fun getQuestion(): String? {
    return question
}

fun setQuestion(question: String) {
    this.question = question
}

fun getOpt1(): String? {
    return option1
}

fun setOpt1(option1: String) {
    this.option1 = option1
}

fun getOpt2(): String? {
    return option2
}

fun setOpt2(option2: String) {
    this.option2 = option2
}

fun getOpt3(): String? {
    return option3
}

fun setOpt3(option3: String) {
    this.option3 = option3
}

fun getAnswerNo(): Int {
    return answerNr
}

fun setAnswerNo(answerNr: Int) {
    this.answerNr = answerNr
}

override fun writeToParcel(parcel: Parcel, flags: Int) {
    parcel.writeString(question)
    parcel.writeString(option1)
    parcel.writeString(option2)
    parcel.writeString(option3)
    parcel.writeInt(answerNr)
}

override fun describeContents(): Int {
    return 0
}

companion object CREATOR : Parcelable.Creator<Question> {
    override fun createFromParcel(parcel: Parcel): Question {
        return Question(parcel)
    }

    override fun newArray(size: Int): Array<Question> {
        return newArray(size)
    }
}

}

【问题讨论】:

    标签: android kotlin exception parcelable onsaveinstancestate


    【解决方案1】:

    在 onSaveInstanceState 方法中,你是先调用 super 然后存储状态。所以 list 始终为 null 并且您已将列表声明为不可为 null,因此它会引发异常。

    更新代码:

     override fun onSaveInstanceState(outState: Bundle?, outPersistentState: PersistableBundle?) {
                outState?.putInt(KEY_SCORE, score)
                outState?.putInt(KEY_QUES_COUNT, questionCounter)
                outState?.putBoolean(KEY_ANSWERED, answered)
                outState?.putLong(KEY_MILLIS_LEFT, timeLeftInMillis)
                outState?.putParcelableArrayList(KEY_QUES_LIST, list)
                super.onSaveInstanceState(outState, outPersistentState)
            }
    

    【讨论】:

    • 我已经在onCreate()中初始化了列表
    • 我明白,我想说的是 list 是非空类型,但 savedInstanceState.getParcelableArrayList(KEY_QUES_LIST) 行返回空。我已经提到了它返回 null 的原因。
    • 我按照你的解决方案做了,但是不行!
    【解决方案2】:

    问题在于如何定义list 以及如何从Bundle 恢复它。恢复保存的实例状态时,getParcelableArrayList() 的返回值可以为空。所以你的代码需要看起来像这样:

    val restoredList = savedInstanceState.getParcelableArrayList(KEY_QUES_LIST)
    restoredList?.also {
        list = it
    }
    

    【讨论】:

    • 我是这样定义的:private var list: ArrayList = arrayListOf()
    • 根据新的细节更新了答案。
    • 你现在看到了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多