本质
挂起函数为什么能被挂起恢复呢?难道靠suspend关键字描述函数就可以了?其实本质还是回调,只不过Kotlin编译器帮我们实现了而已。
将以下代码反编译看看
//定义挂起函数
suspend fun test() {
val resultA = getA()
val resultB = getB()
}
suspend fun getA(): String {
return "A"
}
suspend fun getB(): String {
return "B"
}
//将getA函数反编译看看
public final Object getA(@NotNull Continuation<String> $completion) {//2
//执行耗时任务
return "A";
}
- 注释1:定义了挂起函数getName;
- 注释2:反编译后看到,suspend关键字没有了,函数返回值为Object,增加入参Continuation<String> $completion,泛型String为函数返回值;
Continuation是什么玩意?
public interface Continuation<in T> {//1
/**
* The context of the coroutine that corresponds to this continuation.
*/
public val context: CoroutineContext//2
/**
* Resumes the execution of the corresponding coroutine passing a successful or failed [result] as the
* return value of the last suspension point.
*/
public fun resumeWith(result: Result<T>)//3
}
- 注释1:Continuation是一个接口,是不是有点回调的味道;
- 注释2:维护协程上下文(Dispatchers、异常处理器等);
- 注释3:回调接口,将结果回调到挂起点,然后执行后续的代码;
Java访问挂起函数
public void test(){
new A().getA(new Continuation<String>() {
@NonNull
@Override
public CoroutineContext getContext() {
return null;
}
@Override
public void resumeWith(@NonNull Object o) {
}
});
}
是不是又看到了回调的影子了。
那么具体协程是怎么实现挂起跟恢复的呢?有点复杂,有兴趣的可以关注下后续的分析。
网友评论