- 需求分析
- 效果展示
- Coding
需求分析
如何让普通函数适配协程,成为“真正的挂起函数”。即让调用方以同步的方式拿到异步任务返回结果
//场景描述
fun getConfigContent(){
parseAssetsFile("config.json"){fileContent->
println(fileContent)
}
}
//CoroutineScene4.kt
fun parseAssetsFile(fileName:String,callback(String)->Unit){
Thread(Runnable {
//readfile(filename)
Thread.sleep(2000)
callback("assets file content")
}).start()
}
}
复制代码
方案一
lifecycleScope.launch{
val fileContent = lifecycleScope.async{parseAssetsFile()}.await()
//delay()
println(fileContent)
}
suspend parseAssetsFile(fileName:String):String{
return "assets file content"
}
复制代码
方案二
lifecycleScope.launch{
val fileContent = parseAssetsFile()
println(fileContent)
}
suspend parseAssetsFile(fileName:String):String{
//suspendCoroutine
return suspendCancellableCoroutine { continuation ->
Thread{
//io ....
continuation.resumeWith(Result.success("assets file content"))
}.start()
}
}
复制代码
public suspend fun delay(timeMillis: Long) {
return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont)
}
}
复制代码
一个例子
/**
*
* @Author: jarrysong
* @CreateDate: 2021/4/8 0:24
* @Description: 演示以异步的方式,读取assets目录下的文件,并且适配协程的写法,让他真正的挂起函数
*
* 方便调用,直接以同步的形式拿到返回值
* @Version:
*/
object CoroutineScene3 {
private const val TAG = "CoroutineScene3"
suspend fun parseAssetFile(assManager:AssetManager,fileName:String):String{
return suspendCancellableCoroutine { continuation ->
Thread(Runnable{
val inputStream = assManager.open(fileName)
val br = BufferedReader(InputStreamReader(inputStream))
var line:String?
var stringBuilder = StringBuffer()
do{
line = br.readLine();
if(line != null) stringBuilder.append(line) else break
}while (true)
inputStream.close()
br.close()
Thread.sleep(2000)
Log.i(TAG,"parseassetsfile completed")
continuation.resumeWith(Result.success(stringBuilder.toString()))
}).start()
}
}
}
复制代码
调用
lifecycleScope.launch {
val content = CoroutineScene3.parseAssetFile(assets ,"file.json")
Log.i(TAG,content)
}
Log.i(TAG,"start")
复制代码
注意:
在Activity中建议用lifecycleScope.launch来启动携程,会随着Activity的生命周期自动销毁携程。
如果用GlobalScope.launch来启动,生命周期是Application,会导致内存泄漏。
Retrofit如何适配携程
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END