【问题标题】:Kotlin URL().readText() crashes applicationKotlin URL().readText() 使应用程序崩溃
【发布时间】:2021-04-21 16:06:46
【问题描述】:

我正在尝试从我的网站上获取一些文本并对其进行祝酒,但我在运行时收到 android.os.NetworkOnMainThreadError

var str = URL("https://server.necrodragon41.repl.co/server/connect").readText(Charset.forName("ISO-8859-1"))
Toast.makeText(applicationContext, str, Toast.LENGTH_SHORT).show()

应用程序崩溃了。这是我的代码:

RegisterBtn.setOnClickListener {
            if (day.toString() != "0" && month.toString() != "0" && year.toString() != "0") {
                try {
                    var t = Thread(Runnable {
                        var str = URL("https://server.necrodragon41.repl.co/server/connect").readText(Charset.forName("ISO-8859-1"))
                        Toast.makeText(applicationContext, str, Toast.LENGTH_SHORT).show()
                    })
                    t.start()
                } catch (e: Exception) {
                    Toast.makeText(applicationContext, e.toString(), Toast.LENGTH_SHORT).show()
                }
            } else {
                ErrorText.text = "The date is invalid."
                ErrorText.visibility = View.VISIBLE
            }
        }

我尝试创建线程,因为我得到了错误(在将代码放入线程之前)。如何在不使应用崩溃的情况下获取字符串?

【问题讨论】:

    标签: android string multithreading kotlin url


    【解决方案1】:

    在 android 上,您不能在 (UI/Main)Thread 上发出网络请求,这会冻结应用程序。

    要处理这种情况,您需要使用不同的线程。 由于您使用的是 kotlin,因此您可以执行以下操作:

    lifecycleScope.launchWhenCreated {
        withContext(Dispatchers.IO) {
            // network call
        }
    }
    

    这使用了生命周期扩展,所以为了使用它,请添加 implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0" 在您的应用级别 build.gradle

    您也可以使用 Java 执行器。

    private val executor = Executors.newSingleThreadExecutor()
    
    // use the executor on method
    executor.execute {
       // network call
       runOnUiThread { 
           // update UI
       }
    }
    
    

    另外,由于网络需要在主线程之外处理,UI 更改必须发生在 UI 线程上。

    由于您似乎是在android上说明,如果您有时间,请阅读Arch Guide。 Google 在Udacity 上有一个不错的课程。

    【讨论】:

    • 当我使用executors 并且程序无法识别lifecycleScope 时,应用程序同样崩溃
    • 对不起,我忘了说虽然网络请求需要在另一个线程上运行,但接口相关的更改需要在(UI/Main)线程上运行。
    • 要使用lifecycleScope,需要在app级build.gradle添加Jetpack Lifecycle依赖: implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0" implementation "androidx.lifecycle:生命周期扩展:2.2.0"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-10
    相关资源
    最近更新 更多