Reputation: 2524
I have to call an API asynchronously. To do it i'm using a coroutine, but i have to wait until the API is called to load the data. The problem is the next:
The await is not working as I want, it's not waiting until the API gives all the data.
Is the await what I need? Here is the code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_see)
launch { loaddata() }
/* some other code here*/
}
suspend fun loadData(){
val readData = async { read() }
readData.join()
readData.await()
val showScreen = async { refreshList() }
showScreen.join()
showScreen.await()
}
fun read(){
val stringRequest = object : StringRequest(Request.Method.POST, URL, Response.Listener<String>{ s ->
try {
val array = JSONArray(s)
for (i in 0..array.length() - 1) {
val objectAccount = array.getJSONObject(i)
val account = Account(
objectAccount.getString(value),
objectAccount.getString(value),
objectAccount.getString(value))
listAccount.add(account)
}
}catch (e: JSONException){
e.printStackTrace()
}
}, Response.ErrorListener { error: VolleyError? -> Log.e("error", "error") }){
override fun getParams(): Map<String, String> {
val params = HashMap<String, String>()
params.put("password", value)
params.put("idaccount", value)
return params
}
}
val requesQueue = Volley.newRequestQueue(this)
requesQueue.add<String>(stringRequest)
}
Upvotes: 2
Views: 1709
Reputation: 550
Usually you shouldn't call a async function
requesQueue.add<String>(stringRequest)
in the async
coroutine builder
async {}
Sulution #1
you can change your read()
method to a synchronous request.
Can I do a synchronous request with volley?
and run it with CommonPool
async(CommonPool) {
read()
}
Solution #2
wrap your async http call into a suspend function
I am NOT familiar with Volley, so maybe the code needs tweak
suspend fun read() {
return suspendCancellableCoroutine { continuation ->
val stringRequest = object : StringRequest(Request.Method.POST, URL, Response.Listener<String> { s ->
try {
val array = JSONArray(s)
for (i in 0..array.length() - 1) {
val objectAccount = array.getJSONObject(i)
val account = Account(
objectAccount.getString(value),
objectAccount.getString(value),
objectAccount.getString(value))
listAccount.add(account)
}
} catch (e: JSONException) {
e.printStackTrace()
// notice this
continuation.resumeWithException(e)
}
// notice this
continuation.resume()
}, Response.ErrorListener { error: VolleyError? ->
Log.e("error", "error")
// notice this
if (!continuation.isCancelled)
continuation.resumeWithException()
}) {
override fun getParams(): Map<String, String> {
val params = HashMap<String, String>()
params.put("password", value)
params.put("idaccount", value)
return params
}
}
val requesQueue = Volley.newRequestQueue(this)
requesQueue.add<String>(stringRequest)
continuation.invokeOnCompletion {
if (continuation.isCancelled)
try {
cancel()
} catch (ex: Throwable) {
//Ignore cancel exception
}
}
}
}
and call it like this
suspend fun loadData(){
read()
val showScreen = async { refreshList() }
showScreen.join()
showScreen.await()
}
Upvotes: 1