Issue
This Kotlin routine which I cobbled together from various forum examples works BUT ONLY ON THE FIRST CALL.
class myClass: Activity(), myInterface {
override fun onCreate(...) {
...
}
override fun myCallback(response: String) {
myReturningFunction(response)
}
fun myCallingFunction() {
...
...
val myServer = myObject
myServer.myObjectInit(this, stringData)
//myServer.execute(stringData)
}
}
interface myInterface {
fun myCallback(response: String)
}
object myObject : AsyncTask<String, String, String>() {
var thisInterface: myInterface? = null
fun myObjectInit(thatInterface: myInterface, stringData: String) {
thisInterface = thatInterface
//this.executeOnExecutor(THREAD_POOL_EXECUTOR)
this.execute(stringData)
}
override fun doInBackground(vararg params: String): String? {
var response: String = ""
//return try {
try {
params.first().let {
val url = URL("- web service URL -")
val urlConnect = url.openConnection() as HttpURLConnection
with(urlConnect) {
requestMethod = "POST"
readTimeout = 5000
connectTimeout = 5000
doInput = true
doOutput = true
setRequestProperty("Content-Type", "application/json")
setRequestProperty("Accept", "application/json")
setRequestProperty("Charset", "utf-8")
val jsonByteData = it.toByteArray(Charsets.UTF_8)
outputStream.write(jsonByteData, 0, jsonByteData.size)
outputStream.flush()
outputStream.close()
//inputStream.bufferedReader().readText()
response = inputStream.bufferedReader().readText()
inputStream.close()
disconnect()
}
}
} catch (e: Exception) {
response = ""
}
return response
}
override fun onPostExecute(result: String?) {
when {
result != null -> {
thisInterface?.myCallback(result)
}
else -> {
println("null response")
}
}
}
}
I instantiate a copy of the AsyncTask object and execute it, and when I successfully receive the response via the interface, I instantiate another copy (val myServer = myObject
) for a follow-up call, but this time it throws this error:
Cannot execute task: the task is already running.
I've tried many approaches, closing the input stream, disconnecting from the server, cancelling the task, but none of it works.
Is there something obviously wrong with the code that I'm missing?
TIA.
Solution
An AsyncTask
can only be executed once. If you want to execute it again, you'll need to create a second one.
From the documentation:
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
What you could do is subclass the AsnycTask
and use a new instance each time you want to execute it:
fun startBackgroundTask(){
CustomAsyncTask().execute()
// Or in your case:
CustomAsyncTask().myObjectInit(this, "data")
}
class CustomAsyncTask: AsyncTask<String, String, String>(){
var thisInterface: myInterface? = null
fun myObjectInit(thatInterface: myInterface, stringData: String) {
thisInterface = thatInterface
execute(stringData)
}
override fun doInBackground(vararg params: String?): String {
// Do your work.
return ""
}
}
Answered By - Markus Penguin
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.