Coroutine调用API Android

问题描述 投票:0回答:1

我必须异步调用API。要做到这一点,我正在使用协程,但我必须等到调用API来加载数据。问题是下一个:

await不能按我的意愿工作,它不会等到API提供所有数据。

等待我需要的是什么?这是代码:

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)
}
android asynchronous async-await kotlin coroutine
1个回答
1
投票

通常你不应该叫async function

requesQueue.add<String>(stringRequest)

async协同建设者

async {}

解决方案#1

您可以将read()方法更改为同步请求。 Can I do a synchronous request with 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()
}
© www.soinside.com 2019 - 2024. All rights reserved.