我正在android studio中工作,并且正在使用kotlin协程从API检索结果。
我需要等到协程完成后,才能从中分配一个全局变量。
我已经测试了URL,没关系。 我尝试了正常的线程,该线程可以工作,但是无法让主线程等待其完成。
我尝试使用Fuel.get(),但工作正常,但想使用URL()。
var response = "";
val req = "url.com"
runBlocking { launch {
response = URL(req).readText()
} }
谁能告诉我为什么此代码不起作用?它引发了NetworkOnMainThreadException,但被包装在协程中。
答案 0 :(得分:0)
尝试这种方式
var response = "";
val req = "url.com"
runBlocking<Unit> {
GlobalScope.launch {
response = URL(req).readText()
}
//Work with the response here
}
您可以预览所有协程文档here
答案 1 :(得分:0)
如果只想在另一个线程中处理URL(req).readText()
的结果,请执行以下代码。
var response = "";
val req = "url.com"
runBlocking<Unit> {
GlobalScope.launch {
response = URL(req).readText()
//here is another thread,handle response here
}
//here is main thread, you can't get the result of URL(req).readText() because io operation need a long time .
}
如果在主线程中处理结果,请使用Hanlder类
答案 2 :(得分:0)
我修复了它。最终使用AsyncTask
读取URL,并使用Handler
安排处理结果。
var response = ""
@SuppressLint("StaticFieldLeak")
inner class Retriever : AsyncTask<String, String, String>() {
override fun doInBackground(vararg args : String?): String {
val urlRequest = args[0].toString()
var urlResponse = "";
//Try to extract url
try {
urlResponse = URL(urlRequest).readText()
println("SUCCESS in Retrieve.")
} catch (e : Exception) {
println("EXCEPTION in Retrieve.")
e.printStackTrace()
}
return urlResponse;
}
//Assigns value to response
override fun onPostExecute(result: String?) {
response = result.toString() //Result possibly void type
}
}
override fun onCreate() {
Retriever().execute("url.com")
Handler().{/*Handle response here*/, 10000)
}
答案 3 :(得分:0)
对我来说,以下代码可以正常运行。
var response = "";
val req = "yoururl.com"
runBlocking {
try {
withTimeout(5000) { // 5 seconds for timeout
launch(Dispatchers.IO) { // using IO Dispatcher and not the default
response = URL(req).readText()
} // launch
} // timeout
} catch (e:Exception) { // Timeout, permission, URL or network error
response="Error" // Here one uses a not valid message
}
// Here one manages 'response' variable for error handling or valid output.
在AndroidManifest.xml
主manifest
标签内添加权限也很重要:
<uses-permission android:name="android.permission.INTERNET"/>
(对于时间不太长的任务)这种方法的优点是简单,因为它是顺序代码,因此不需要使用callback
例程。