我无法在协程内部的catch块中进行数据绑定更改。为什么?

在我的启动活动期间,我希望我的应用程序ping服务器并执行一些快速检查。如果失败,我想显示一个选项,以重试,或者继续使用互联网。这是一些基本的初始化:

private lateinit var binding: ActivitySplashBinding
private val response = MutableLiveData<String>()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // enable databinding with layout files
    binding = DataBindingUtil.setContentView(this, R.layout.activity_splash)
    response.value = "Initializing ..."
    response.observe(this, Observer {
        binding.statusText.text = it
    })
    // set up button click listeners here too, omitted for brevity
    checkInternet()

}

在onCreate中设置一些TextView值可以很好地工作,因此我知道数据绑定正在工作。

private var job = Job()
private val checkScope = CoroutineScope(job + Dispatchers.IO)

private fun checkInternet() {
    binding.apply {
        buttonTryAgain.visibility = View.GONE
        buttonContinue.visibility = View.GONE
    }
    response.postValue("Checking internet connection...")
    checkScope.async {
        try {
            myApi.retrofitService.getFoo() // this is synchronous
            startNextActivity()
        } catch (e: Exception) {
            Log.i(TAG, "Start exception block")
            response.postValue("Hm, it seems we're unable to reach the server. Check your internet connection?")
            binding.apply {
                buttonTryAgain.visibility = View.VISIBLE
                buttonContinue.visibility = View.VISIBLE
            }
            Log.i(TAG, "We never reach here, why?")
        }
    }
}

I test by putting the device into airplane mode, and the call to binding.apply in the catch block never completes. Why? Also, assuming there's a exception here (and async doesn't rethrow exceptions), how can I see it?

评论
xsint
xsint

I think you've been a victim of a failed lifecycle owner

绑定类具有一个称为setLifecycleOwner的方法,该方法必须   从数据绑定布局观察LiveData时调用。

Make sure to add the necessary lifecycle owner when working with Databinding and LiveData

更新的代码;

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // enable databinding with layout files
    binding = DataBindingUtil.setContentView(this, R.layout.activity_splash)

    binding.lifecycleOwner = this          // this was missing

    response.value = "Initializing ..."
    response.observe(this, Observer {
        binding.statusText.text = it
    })
    // set up button click listeners here too, omitted for brevity
    checkInternet()
点赞
评论