尝试更改观察者内部的 MutableLiveData 值时应用程序没有响应

The app not responding when try to change MutableLiveData value inside observer

在这个应用“猜一猜”游戏中,我试图检测当用户到达 wordList 末尾时游戏何时结束,在 GameViewModel 中 _eventGameFinish val 负责

GameViewModel

class GameViewModel : ViewModel() {


    // The current word
    private val _word = MutableLiveData<String>()
    val word: LiveData<String>
        get() = _word


    // The current score
    private val _score = MutableLiveData<Int>()
    val score: LiveData<Int>
        get() = _score


    private val _eventGameFinish = MutableLiveData<Boolean>()
    val eventGameFinish : LiveData<Boolean>
            get()= _eventGameFinish


    // The list of words - the front of the list is the next word to guess
    private lateinit var wordList: MutableList<String>

    init {
        Log.i("GameViewModel", "GameViewModel created!")
        resetList()
        nextWord()
        _score.value = 0
        _eventGameFinish.value = false
    }

    /**
     * Resets the list of words and randomizes the order
     */
    private fun resetList() {
        wordList = mutableListOf(
            "queen",
            "hospital",
            "basketball",
            "cat",
            "change",
            "snail",
            "soup",
            "calendar",
            "sad",
            "desk",
            "guitar",
            "home",
            "railway",
            "zebra",
            "jelly",
            "car",
            "crow",
            "trade",
            "bag",
            "roll",
            "bubble"
        )
        wordList.shuffle()
    }

    /**
     * Moves to the next word in the list
     */
    private fun nextWord() {
        //Select and remove a word from the list
        if (wordList.isEmpty()) {
            _eventGameFinish.value = true
        } else {
            _word.value = wordList.removeAt(0)
        }
    }

    /** Methods for buttons presses **/

    fun onSkip() {
        _score.value = score.value?.minus(1)
        nextWord()
    }

    fun onCorrect() {
        _score.value = score.value?.plus(1)
        nextWord()
    }

    fun onGameFinishComplete(){
        _eventGameFinish.value = false
    }

    override fun onCleared() {
        super.onCleared()
        Log.i("GameViewModel", "GameViewModel destroyed")
    }
}

在 GameFragment 中,我在 eventGameFinish 上观察,然后调用 gameViewModel.onGameFinishComplete() 以在片段中仅执行一次操作

这里是 GameFragment class

class GameFragment : Fragment() {

    private lateinit var gameViewModel: GameViewModel


    private lateinit var binding: GameFragmentBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        // Inflate view and obtain an instance of the binding class
        binding = DataBindingUtil.inflate(
            inflater,
            R.layout.game_fragment,
            container,
            false
        )

        Log.i("GameViewModelOf", "GameViewModelOf")
        gameViewModel = ViewModelProvider(this).get(GameViewModel::class.java)



        binding.correctButton.setOnClickListener {

            gameViewModel.onCorrect()

        }
        binding.skipButton.setOnClickListener {
            gameViewModel.onSkip()

        }


        gameViewModel.score.observe(viewLifecycleOwner, Observer { newScore ->
            binding.scoreText.text = newScore.toString()
        })

        gameViewModel.word.observe(viewLifecycleOwner, Observer { newWord ->
            binding.wordText.text = newWord

        })

        gameViewModel.eventGameFinish.observe(viewLifecycleOwner, Observer { eventGameFinish ->
            if (eventGameFinish) this.gameFinished()
            gameViewModel.onGameFinishComplete()
        })

        return binding.root

    }


    /**
     * Called when the game is finished
     */
    private fun gameFinished() {
//        val action = GameFragmentDirections.actionGameToScore(gameViewModel.score.value ?: 0)
//        findNavController(this).navigate(action)
        Toast.makeText(this.activity, "Game finished", Toast.LENGTH_SHORT).show()
    }
}

问题出在这一行 gameViewModel.onGameFinishComplete() 当我在 Observer 块中调用方法时 运行 应用程序没有任何异常响应,如果我删除了这个方法调用,应用程序是工作正常,但我无法在到达 wordList

末尾时更改 eventGameFinish 的值

您正在观察“eventGameFinish”,如果它是真的,它将调用 gameFinished() 方法和 onGameFinishComplete() 代码将新值设置为 eventGameFinish.so 观察者将再次观察到新值。现在它是假的,它将一次又一次地调用 gameViewModel() 并设置 false.that 是你收到 ANR 的原因。

因此仅当实时数据值为 true.OR 时才调用方法,在游戏结束后使用单独的 MutableLiveData 数据设置值。

  if (eventGameFinish) 
{
    this.gameFinished()
    gameViewModel.onGameFinishComplete()
}