协程调用 API Android

Coroutine calling API Android

我必须异步调用 API。为此,我正在使用协程,但我必须等到 API 被调用才能加载数据。问题是下一个:

等待没有如我所愿地工作,它没有等到 API 提供所有数据。

await 是我需要的吗?这是代码:

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)
}

通常你不应该调用 async function

requesQueue.add<String>(stringRequest)

async 协程构建器中

async {}

解决方案#1

您可以将 read() 方法更改为同步请求。 我可以使用 volley 进行同步请求吗? 运行 和 CommonPool

async(CommonPool) {
    read()
}

解决方案 #2

将您的异步 http 调用包装到 suspend function

我不熟悉 Volley,所以代码可能需要调整

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
                }
        }
    }
}

然后这样称呼它

suspend fun loadData(){

    read()

    val showScreen = async { refreshList() }
    showScreen.join()
    showScreen.await()
}