0

我有一些启动请求的 splashScreen,其中数据被加载到应用程序中。在我发起这些 splashScreen 请求之前,我想检查连接。这部分工作正常,但如果应用程序无法访问互联网,我想每 2 秒检查一次连接。如果建立连接,我想取消Timer/TimerTask并执行Timer调用下的代码(隐藏重新连接progressBar和Text并再次调用服务器api)。但是,如果我在下面运行此代码,应用程序将崩溃,而 Logcat 中不会出现任何错误。但是我可以看到从 TimerTask 重新连接日志仍在运行。

我试图移动api.splashScreen(this)hideReconnectViews()进入 ReconnectCheck 类并通过上下文调用它们,但这会抛出异常:

android.view.ViewRoot$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。

任何想法为什么我的解决方案不起作用?

SplashScreen 活动中的代码:

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()
        }

重新连接检查类:

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")
        }
    }
}
4

1 回答 1

0

您的 run 方法在与主线程不同的线程上执行。获取主线程并在那里更改您的视图。 @JacksOnF1re

代码:

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")
        }
    }
}

这行得通。

于 2018-09-03T14:12:13.720 回答