协程调用 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()
}
我必须异步调用 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()
}