Search code examples
android-studiokotlinrunnable

How do you know when a thread has finished executing


I am doing a quiz app in Android studio using Kotlin. I am fetching data from an API and showing it in an activity. Now I am implementing a progressBar that indicates how much time to answer each question. This is my function to fetch from API:

 private fun fetch(){

    val theme = intent.getIntExtra("sport", 21)
    val difficulty = intent.getStringExtra("medium")

    val url = "https://opentdb.com/api.php?amount=10&category=21&difficulty=medium&type=multiple"
    val request = Request.Builder()
        .url(url)
        .build()

    client.newCall(request).enqueue(object: Callback {

        override fun onResponse(call: Call, response: Response) {

            val body = response.body?.string()
            val gson = GsonBuilder().create()
            val triviaRequest = gson.fromJson(body, TriviaRequest::class.java)
            val result = triviaRequest.results[0]
            val question = result.question.toSpanned()
            val questionCategory = result.category.toSpanned()
            val correctAnswer = result.correct_answer.toSpanned()
            val incorrectAnswer1 = result.incorrect_answers[0].toSpanned()
            val incorrectAnswer2 = result.incorrect_answers[1].toSpanned()
            val incorrectAnswer3 = result.incorrect_answers[2].toSpanned()

            val questions = listOf(
                correctAnswer,
                incorrectAnswer1,
                incorrectAnswer2,
                incorrectAnswer3
            )

            shuffle(questions)

            runOnUiThread {

                val button1 = findViewById<Button>(R.id.alternative1)
                val button2 = findViewById<Button>(R.id.alternative2)
                val button3 = findViewById<Button>(R.id.alternative3)
                val button4 = findViewById<Button>(R.id.alternative4)

                questionText.text = question
                themeText.text = questionCategory

                button1.text = questions[0]
                button1.isEnabled = true

                button2.text = questions[1]
                button2.isEnabled = true

                button3.text = questions[2]
                button3.isEnabled = true

                button4.text = questions[3]
                button4.isEnabled = true

                button1.setOnClickListener {

                    button1.isClickable = false
                    if (button1.text == correctAnswer) {
                        score += 1
                        fetch()
                    } else {
                        button1.text = "---"
                    }
                }

                button2.setOnClickListener {

                    button2.isClickable = false
                    if (button2.text == correctAnswer) {
                        score += 1
                        fetch()
                    } else {
                        button2.text = "---"
                    }
                }

                button3.setOnClickListener {

                    button3.isClickable = false
                    if (button3.text == correctAnswer) {
                        score += 1
                        fetch()
                    } else {
                        button3.text = "---"
                    }
                }

                button4.setOnClickListener {

                    button4.isClickable = false
                    if (button4.text == correctAnswer) {
                        score += 1
                        fetch()
                    } else {
                        button4.text = "---"
                    }
                }
            }
            response.close()
        }

        override fun onFailure(call: Call, e: IOException) {
            e.printStackTrace()
        }

    })
}

And this is how I show the progressBar:

  val fetch = runCatching { fetch() }
        if(fetch.isSuccess) {
            val handler = Handler()
            Thread(Runnable {

                while (progressCount < 100) {
                    progressCount += 1
                    try {
                        Thread.sleep(50)
                    } catch (e: InterruptedException) {
                        e.printStackTrace()
                    }
                    handler.post {
                        progressBar.progress = progressCount
                    }
                }
            }).start()
        }

    }

The problem now is that as soon as the activity starts, my progressBar starts showing but the questions has not appeared yet. My question is how can I know when my fetch function has finished executing? so that I can show the progressBar?

Thanks!


Solution

  • You can look into kotlin coroutines and use suspend functions, or you can use a callback like this:

    fun fetch (callback: ()->Unit) { // take callback param
    
       ... // do the stuff
    
       callback() // call the callback on complete
    
    }
    
    fetch {
        // Done fetching here, execute your code inside this
    }