0

I have splashScreen with some startup requests where data are loaded into the app. Before I initiate those splashScreen requests, I want to check connection. This part is working fine, but if app doesn't have access to the internet, I want to check connection every 2 seconds. If connection is established, I want to cancel Timer/TimerTask and execute code under Timer call(hiding reconnecting progressBar and Text and call server api again). But if I run this code below, app will crash without any error visible in Logcat. But I can see Reconnecting Log from TimerTask still running.

I've tried to move api.splashScreen(this) and hideReconnectViews() into the ReconnectCheck class and call those via context, but this throw exception:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Any ideas why my solution doesn't work?

Code in SplashScreen activity:

const val RECONNECT_TIME: Long = 2000

if(isOnline()){
            api.splashScreen(this)
        } else {
            showReconnectViews()
            val reconnectTimer = Timer()
            reconnectTimer.schedule(ReconnectCheck(this, reconnectTimer), 0, RECONNECT_TIME)
            createLog("ReconnectCheck ", "TimerFinished")
            api.splashScreen(this)
            hideReconnectViews()
        }

ReconnectCheck class:

class ReconnectCheck(val ctx: Context, val timer: Timer): TimerTask() {

    override fun run() {
        if ((ctx as Splash).isOnline()){
            timer.cancel()
            timer.purge()
        } else {
            Log.i("ReconnectCheck: ", "Reconnecting")
        }
    }
}
martin1337
  • 2,384
  • 6
  • 38
  • 85
  • 1
    Your run method is executed on a different thread than the main thread. Get the main thread and change your views there. But anyway, usually it is not a good idea to do such operations using timers. Let the user decide to try again, use a service or use viewmodels. – JacksOnF1re Sep 03 '18 at 13:54

1 Answers1

0

Your run method is executed on a different thread than the main thread. Get the main thread and change your views there. @JacksOnF1re

Code:

class ReconnectCheck(val ctx: Context, val timer: Timer): TimerTask() {
    private val api: API = API.getInstance(ctx)

    override fun run() {
        if ((ctx as Splash).isOnline()){
            ctx.runOnUiThread {
                ctx.hideReconnectViews()
                api.splashScreen(ctx)
            }
            timer.cancel()
            timer.purge()
        } else {
            Log.i("ReconnectCheck: ", "Reconnecting")
        }
    }
}

This worked.

martin1337
  • 2,384
  • 6
  • 38
  • 85