@@ -20,7 +20,7 @@ package retrofit2
20
20
21
21
import kotlinx.coroutines.Dispatchers
22
22
import kotlinx.coroutines.suspendCancellableCoroutine
23
- import java.lang.reflect.ParameterizedType
23
+ import kotlinx.coroutines.withContext
24
24
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
25
25
import kotlin.coroutines.intrinsics.intercepted
26
26
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
@@ -30,57 +30,63 @@ import kotlin.coroutines.resumeWithException
30
30
inline fun <reified T : Any > Retrofit.create (): T = create(T ::class .java)
31
31
32
32
suspend fun <T : Any > Call<T>.await (): T {
33
- return suspendCancellableCoroutine { continuation ->
34
- continuation.invokeOnCancellation {
35
- cancel()
36
- }
37
- enqueue(object : Callback <T > {
38
- override fun onResponse (call : Call <T >, response : Response <T >) {
39
- if (response.isSuccessful) {
40
- val body = response.body()
41
- if (body == null ) {
42
- val invocation = call.request().tag(Invocation ::class .java)!!
43
- val method = invocation.method()
44
- val e = KotlinNullPointerException (" Response from " +
33
+ // TODO: a better solution for off-main-thread call factories than this.
34
+ return withContext(Dispatchers .Default ) {
35
+ suspendCancellableCoroutine { continuation ->
36
+ continuation.invokeOnCancellation {
37
+ cancel()
38
+ }
39
+ enqueue(object : Callback <T > {
40
+ override fun onResponse (call : Call <T >, response : Response <T >) {
41
+ if (response.isSuccessful) {
42
+ val body = response.body()
43
+ if (body == null ) {
44
+ val invocation = call.request().tag(Invocation ::class .java)!!
45
+ val method = invocation.method()
46
+ val e = KotlinNullPointerException (" Response from " +
45
47
method.declaringClass.name +
46
48
' .' +
47
49
method.name +
48
50
" was null but response body type was declared as non-null" )
49
- continuation.resumeWithException(e)
51
+ continuation.resumeWithException(e)
52
+ } else {
53
+ continuation.resume(body)
54
+ }
50
55
} else {
51
- continuation.resume(body )
56
+ continuation.resumeWithException( HttpException (response) )
52
57
}
53
- } else {
54
- continuation.resumeWithException(HttpException (response))
55
58
}
56
- }
57
59
58
- override fun onFailure (call : Call <T >, t : Throwable ) {
59
- continuation.resumeWithException(t)
60
- }
61
- })
60
+ override fun onFailure (call : Call <T >, t : Throwable ) {
61
+ continuation.resumeWithException(t)
62
+ }
63
+ })
64
+ }
62
65
}
63
66
}
64
67
65
68
@JvmName(" awaitNullable" )
66
69
suspend fun <T : Any > Call<T?>.await (): T ? {
67
- return suspendCancellableCoroutine { continuation ->
68
- continuation.invokeOnCancellation {
69
- cancel()
70
- }
71
- enqueue(object : Callback <T ?> {
72
- override fun onResponse (call : Call <T ?>, response : Response <T ?>) {
73
- if (response.isSuccessful) {
74
- continuation.resume(response.body())
75
- } else {
76
- continuation.resumeWithException(HttpException (response))
77
- }
70
+ // TODO: a better solution for off-main-thread call factories than this.
71
+ return withContext(Dispatchers .Default ) {
72
+ suspendCancellableCoroutine { continuation ->
73
+ continuation.invokeOnCancellation {
74
+ cancel()
78
75
}
76
+ enqueue(object : Callback <T ?> {
77
+ override fun onResponse (call : Call <T ?>, response : Response <T ?>) {
78
+ if (response.isSuccessful) {
79
+ continuation.resume(response.body())
80
+ } else {
81
+ continuation.resumeWithException(HttpException (response))
82
+ }
83
+ }
79
84
80
- override fun onFailure (call : Call <T ?>, t : Throwable ) {
81
- continuation.resumeWithException(t)
82
- }
83
- })
85
+ override fun onFailure (call : Call <T ?>, t : Throwable ) {
86
+ continuation.resumeWithException(t)
87
+ }
88
+ })
89
+ }
84
90
}
85
91
}
86
92
@@ -91,19 +97,22 @@ suspend fun Call<Unit>.await() {
91
97
}
92
98
93
99
suspend fun <T > Call<T>.awaitResponse (): Response <T > {
94
- return suspendCancellableCoroutine { continuation ->
95
- continuation.invokeOnCancellation {
96
- cancel()
97
- }
98
- enqueue(object : Callback <T > {
99
- override fun onResponse (call : Call <T >, response : Response <T >) {
100
- continuation.resume(response)
100
+ // TODO: a better solution for off-main-thread call factories than this.
101
+ return withContext(Dispatchers .Default ) {
102
+ suspendCancellableCoroutine { continuation ->
103
+ continuation.invokeOnCancellation {
104
+ cancel()
101
105
}
106
+ enqueue(object : Callback <T > {
107
+ override fun onResponse (call : Call <T >, response : Response <T >) {
108
+ continuation.resume(response)
109
+ }
102
110
103
- override fun onFailure (call : Call <T >, t : Throwable ) {
104
- continuation.resumeWithException(t)
105
- }
106
- })
111
+ override fun onFailure (call : Call <T >, t : Throwable ) {
112
+ continuation.resumeWithException(t)
113
+ }
114
+ })
115
+ }
107
116
}
108
117
}
109
118
0 commit comments