0%

协程原理之如何实现非阻塞式挂起

普通callback实现

与协程异步代码同步写法对比

callback实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//CallbackImpl.kt‭​​‌‌‎‭‬​
abstract class CallbackImpl(val callBack: CallBack<Any>): CallBack<Any> {‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
override fun onResult(result: Any?) {‭​​‌‌‎‭‬​
val cb = callBack‭​​‌‌‎‭‬​
while (true) {‭​​‌‌‎‭‬​
val outcome = invoke(result)‭​​‌‌‎‭‬​
if (outcome === CALLBACK_FLAG) {‭​​‌‌‎‭‬​
return‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
cb.onResult(outcome)‭​​‌‌‎‭‬​
return‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
protected abstract fun invoke(result: Any?): Any?‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
val CALLBACK_FLAG = CoroutineSingletons.CALLBACK‭​​‌‌‎‭‬​
enum class CoroutineSingletons { CALLBACK }‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
interface CallBack<T> {‭​​‌‌‎‭‬​
fun onResult(result: T?)‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
object UserInfoHelper {‭​​‌‌‎‭‬​
fun launch() {‭​​‌‌‎‭‬​
Log.e("MainActivity", "launch run")‭​​‌‌‎‭‬​
requestUserCallback(object : CallBack<Any> {‭​​‌‌‎‭‬​
override fun onResult(result: Any?) {‭​​‌‌‎‭‬​
Log.e("MainActivity", "launch result: $result")‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
})‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
val handler = Handler(Looper.getMainLooper())‭​​‌‌‎‭‬​
private fun delay(timeMillis: Long, callBack: CallBack<Any>): Any {‭​​‌‌‎‭‬​
handler.postDelayed({‭​​‌‌‎‭‬​
callBack.onResult(Unit)‭​​‌‌‎‭‬​
}, timeMillis)‭​​‌‌‎‭‬​
return CALLBACK_FLAG‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
//正常情况下应该保持到协程的context中,这样写为了简单处理‭​​‌‌‎‭‬​
private var userCallback:UserCallback? = null‭​​‌‌‎‭‬​
abstract class UserCallback(callBack: CallBack<Any>) : CallbackImpl(callBack) {‭​​‌‌‎‭‬​
var result: Any? = null‭​​‌‌‎‭‬​
var flag: Int = 0‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
fun requestUserCallback(callBack: CallBack<Any>): Any {‭​​‌‌‎‭‬​
val cb = if (userCallback == null) {‭​​‌‌‎‭‬​
val c = object : UserCallback(callBack) {‭​​‌‌‎‭‬​
override fun invoke(result: Any?): Any? {‭​​‌‌‎‭‬​
this.result = result‭​​‌‌‎‭‬​
++flag‭​​‌‌‎‭‬​
return requestUserCallback(this)‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
userCallback = c‭​​‌‌‎‭‬​
c‭​​‌‌‎‭‬​
}else {‭​​‌‌‎‭‬​
userCallback!!‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
var returnResult = cb.result‭​​‌‌‎‭‬​
when (cb.flag) {‭​​‌‌‎‭‬​
0 -> {‭​​‌‌‎‭‬​
if (requestFriendListCallback(cb) == CALLBACK_FLAG) {‭​​‌‌‎‭‬​
return CALLBACK_FLAG‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
1 -> {‭​​‌‌‎‭‬​
returnResult = cb.result‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
return "user: $returnResult"‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
//正常情况下应该保持到协程的context中,这样写为了简单处理‭​​‌‌‎‭‬​
var requestFriendListCallback: RequestFriendListCallback? = null‭​​‌‌‎‭‬​
abstract class RequestFriendListCallback(callBack: CallBack<Any>) : CallbackImpl(callBack) {‭​​‌‌‎‭‬​
var result: Any? = null‭​​‌‌‎‭‬​
var flag: Int = 0‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
fun requestFriendListCallback(callBack: CallBack<Any>): Any {‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
val cb = if ( requestFriendListCallback == null) {‭​​‌‌‎‭‬​
val c = object : RequestFriendListCallback(callBack) {‭​​‌‌‎‭‬​
override fun invoke(result: Any?): Any? {‭​​‌‌‎‭‬​
this.result = result‭​​‌‌‎‭‬​
++flag‭​​‌‌‎‭‬​
return requestFriendListCallback(this)‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
requestFriendListCallback = c‭​​‌‌‎‭‬​
c‭​​‌‌‎‭‬​
} else {‭​​‌‌‎‭‬​
requestFriendListCallback!!‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
when (cb.flag) {‭​​‌‌‎‭‬​
0 -> {‭​​‌‌‎‭‬​
if (delay(3000, cb) == CALLBACK_FLAG) {‭​​‌‌‎‭‬​
return CALLBACK_FLAG‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
1 -> {‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
 ‭​​‌‌‎‭‬​
return "friendList"‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​
}‭​​‌‌‎‭‬​

协程反编译字节码

1
2