我正在将SDK移植到Kotlin,这基本上是一些网络调用的包装。现有的Java版本使用回调将结果返回给开发人员。据我了解,协程似乎是实现此目的的一种合理方法,但是我在如何返回结果而又不阻塞主线程的问题上苦苦挣扎。
这是我的代码:
MainActivity.java
public void onClickButton(View v) {
OiSDK oiSDK = new OiSDK(new NetworkHandler());
List<Token> tokens = oiSDK.getTokens();
}
OiSDK.kt
fun getTokens() = runBlocking {
Log.d("OiSDK", "getTokens - from thread ${Thread.currentThread().name}")
val tokens = async { fetchTokensFromServer() }.await()
tokens
}
suspend fun fetchTokensFromServer(): List<Token> {
val startTime = System.currentTimeMillis()
Log.d("OiSDK", "fetchTokensFromServer - from thread ${Thread.currentThread().name}")
var tokens = ArrayList<Token>()
val response = networkHandler.networkAPI.authorize(registrationUri,
authorizationHeader, Constants.TOKEN_GRANT_TYPE_AUTHORIZATION_CODE,
code, redirectUrl)
tokens.add(new Token(response))
val endTime = System.currentTimeMillis()
Log.d("OiSDK", "Time taken: ${endTime - startTime}")
return tokens
}
日志跟踪:
2020-03-08 22:18:24.741 11740-11740/D/MainActivity: Update progessBar 14 - from thread main
2020-03-08 22:18:24.844 11740-11740/D/MainActivity: Update progessBar 15 - from thread main
2020-03-08 22:18:24.945 11740-11740/D/MainActivity: Update progessBar 16 - from thread main
2020-03-08 22:18:25.143 11740-11740/D/OiSDK: getTokens - from thread main
2020-03-08 22:18:25.150 11740-11818/D/OiSDK: fetchTokensFromServer - from thread main
2020-03-08 22:18:28.202 11740-11740/D/OiSDK: Time taken: 3058
2020-03-08 22:18:28.217 11740-11740/D/MainActivity: Update progessBar 17 - from thread main
2020-03-08 22:18:28.228 11740-11740/D/MainActivity: Update progessBar 18 - from thread main
2020-03-08 22:18:28.320 11740-11740/D/MainActivity: Update progessBar 19 - from thread main
问题:
runBlocking
阻塞主线程(如在多个地方所述,包括文档)。CoroutineScope(Dispatchers.IO).launch
)将改为使用工作线程进行网络调用,但是getTokens
仍会阻塞主线程。launch
使用任何范围,则不知道如何返回结果。协程是否真的适合此用例,因为我不仅要更新某些UI,还需要返回SDK范围之外的内容?如果是这样:那怎么实现?