Home > Back-end >  MainActivity View appears only after calculations
MainActivity View appears only after calculations

Time:06-10

I am new to Android Development... Sorry for asking something so trivial. I don't know how to google this problem.

So let me explain:

I am doing the Android Development Course from Google and in the exercise you have a TextView that is repeatedly changed by an easy mathematical function 4 times after setContentViewis called. Between the changes Thread.sleep(1000) is called to delay the changes.

Expected behavior:

The Main Activity starts and you can see the TextView changing 4 times.

What actually happens:

The App start is delayed for as long as the calculations are set and then afterwards it will display the Main Activity with only the very last calculated result. In this case I would wait 4 seconds (with Thread.sleep(1000) being called 4 times) until the App is completely up and then you only see the result 60 because of 60 / 1.

This is the code:

private const val TAG = "MainActivity"
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        division()
    }

    private fun division() {
        val numerator = 60
        var denominator = 4
        repeat(4) {
            Thread.sleep(1000)
            Log.v(TAG, "${numerator / denominator}")
            val view: TextView = findViewById(R.id.division_textview)
            view.setText("${numerator / denominator}")
            denominator--
        }
    }

Thanks in advance. I hope someone knows why Google is suggesting this code, but it does not work on my machine.

CodePudding user response:

You need to make a delay by Timer instead of Thread.sleep()

CodePudding user response:

For training you can try something like this.

 private val timerHandler = Handler(Looper.getMainLooper())
 private val timerRunnable = Runnable {
    denominator--
    if(demominator != 0) {
       //UI changes here
       decrementTimer()
    }
 }

 private fun decrementTimer() {
    timerHandler.postDelayed(timerRunnable, DELAY_TIME)
 }

If you need to start first run immediately use timerRunnable.run() in other case call decrementTimer(). Also would be helpful to control handler with removeCallbacks function when activity goes to background

CodePudding user response:

You can wait in another thread so you don't block the main thread, try this code it should work correctly, the code inside the lifecycleScope.launch will be moved to another thread so it will not block the UI:

private const val TAG = "MainActivity"
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    division()
}

private fun division() {
    val numerator = 60
    var denominator = 4
    lifecycleScope.launch {
        repeat(4) {
            delay(1000)
            Log.v(TAG, "${numerator / denominator}")
            val view: TextView = findViewById(R.id.division_textview)
            view.setText("${numerator / denominator}")
            denominator--
        }
    }
}

Note: You need to be sure that you add the lifecycle dependency in you app gradle

dependencies {
    ...
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1'
    ...
}
  • Related