Skip to content

Commit 42b1bcd

Browse files
committed
refactor interceptor
1 parent 802760d commit 42b1bcd

File tree

10 files changed

+99
-75
lines changed

10 files changed

+99
-75
lines changed

gradle/libs.versions.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ espresso-core = "3.5.0"
4242
# router
4343
auto-service = "1.0"
4444
kotlin-poet = "1.10.2"
45-
clarity = "1.0.4"
45+
clarity = "1.0.5"
4646

4747
[libraries]
4848
# plugin

router/src/main/java/com/thoughtworks/ark/router/Data.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package com.thoughtworks.ark.router
22

33
import android.os.Bundle
44
import android.os.Parcelable
5-
import kotlinx.parcelize.Parcelize
65
import com.thoughtworks.ark.router.internal.createRequestId
6+
import kotlinx.parcelize.Parcelize
77

88
@Parcelize
99
data class SchemeRequest(
@@ -16,7 +16,7 @@ data class SchemeRequest(
1616
val flags: Int = 0,
1717
val containerViewId: Int = 0,
1818

19-
val needResult: Boolean = true,
19+
val needResult: Boolean = false,
2020
val enableBackStack: Boolean = true,
2121
val enableGlobalInterceptor: Boolean = true,
2222

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.thoughtworks.ark.router
22

33
class DefaultRouterInterceptor(
4-
private val interceptor: suspend (SchemeRequest) -> Unit
4+
private val interceptor: suspend (SchemeRequest) -> SchemeRequest
55
) : RouterInterceptor {
66
override suspend fun shouldIntercept(request: SchemeRequest): Boolean {
77
return true
88
}
99

10-
override suspend fun intercept(request: SchemeRequest) {
11-
interceptor(request)
10+
override suspend fun intercept(request: SchemeRequest): SchemeRequest {
11+
return interceptor(request)
1212
}
1313
}

router/src/main/java/com/thoughtworks/ark/router/InterceptorManager.kt

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,18 @@ class InterceptorManager {
1111
interceptorList.remove(interceptor)
1212
}
1313

14-
suspend fun intercept(schemeRequest: SchemeRequest) {
15-
val temp = mutableListOf<RouterInterceptor>()
16-
temp.addAll(interceptorList)
14+
suspend fun intercept(schemeRequest: SchemeRequest): SchemeRequest {
15+
val tempInterceptorList = mutableListOf<RouterInterceptor>()
16+
tempInterceptorList.addAll(interceptorList)
1717

18-
temp.forEach {
19-
if (it.shouldIntercept(schemeRequest)) {
20-
it.intercept(schemeRequest)
18+
var tempRequest = schemeRequest
19+
20+
tempInterceptorList.forEach {
21+
if (it.shouldIntercept(tempRequest)) {
22+
tempRequest = it.intercept(tempRequest)
2123
}
2224
}
25+
26+
return tempRequest
2327
}
2428
}

router/src/main/java/com/thoughtworks/ark/router/RouterCore.kt

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
package com.thoughtworks.ark.router
44

5+
import android.content.Context
56
import android.os.Bundle
67
import com.thoughtworks.ark.router.dispatcher.SchemeDispatcher
78
import com.thoughtworks.ark.router.dispatcher.ServiceDispatcher
@@ -10,7 +11,7 @@ import kotlinx.coroutines.FlowPreview
1011
import kotlinx.coroutines.flow.Flow
1112
import kotlinx.coroutines.flow.flatMapConcat
1213
import kotlinx.coroutines.flow.flowOf
13-
import kotlinx.coroutines.flow.onEach
14+
import kotlinx.coroutines.flow.map
1415

1516
object RouterCore {
1617
private val moduleManager = ModuleManager()
@@ -42,16 +43,25 @@ object RouterCore {
4243

4344
fun queryService(identity: String): ServiceRequest = moduleManager.queryService(identity)
4445

45-
fun dispatchScheme(request: SchemeRequest, interceptorManager: InterceptorManager): Flow<Result<Bundle>> {
46-
return flowOf(Unit).onEach {
47-
if (request.enableGlobalInterceptor) {
48-
this.interceptorManager.intercept(request)
46+
fun dispatchScheme(
47+
context: Context,
48+
request: SchemeRequest,
49+
interceptorManager: InterceptorManager
50+
): Flow<Result<Bundle>> {
51+
return flowOf(request)
52+
.map {
53+
if (it.enableGlobalInterceptor) {
54+
this.interceptorManager.intercept(it)
55+
} else {
56+
it
57+
}
58+
}
59+
.map {
60+
interceptorManager.intercept(it)
61+
}
62+
.flatMapConcat {
63+
schemeDispatcher.dispatch(context, it)
4964
}
50-
}.onEach {
51-
interceptorManager.intercept(request)
52-
}.flatMapConcat {
53-
schemeDispatcher.dispatch(request)
54-
}
5565
}
5666

5767
fun dispatchBack(bundle: Bundle): SchemeRequest? {

router/src/main/java/com/thoughtworks/ark/router/RouterInterceptor.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ package com.thoughtworks.ark.router
22

33
interface RouterInterceptor {
44
suspend fun shouldIntercept(request: SchemeRequest): Boolean
5-
suspend fun intercept(request: SchemeRequest)
5+
suspend fun intercept(request: SchemeRequest): SchemeRequest
66
}

router/src/main/java/com/thoughtworks/ark/router/SchemeHandler.kt

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
package com.thoughtworks.ark.router
22

3+
import android.content.Context
34
import android.os.Bundle
45
import androidx.core.os.bundleOf
5-
import androidx.lifecycle.Lifecycle
6-
import kotlinx.coroutines.CoroutineScope
6+
import com.thoughtworks.ark.router.internal.InternalHelper.findActivity
7+
import com.thoughtworks.ark.router.internal.InternalHelper.findScope
8+
import com.thoughtworks.ark.router.internal.key
79
import kotlinx.coroutines.FlowPreview
810
import kotlinx.coroutines.flow.*
9-
import com.thoughtworks.ark.router.internal.InternalHelper
10-
import com.thoughtworks.ark.router.internal.key
1111

1212
@OptIn(FlowPreview::class)
1313
class SchemeHandler(
@@ -37,7 +37,7 @@ class SchemeHandler(
3737
return apply { interceptorManager.addInterceptor(interceptor) }
3838
}
3939

40-
fun addInterceptor(interceptor: suspend (SchemeRequest) -> Unit): SchemeHandler {
40+
fun addInterceptor(interceptor: suspend (SchemeRequest) -> SchemeRequest): SchemeHandler {
4141
return apply {
4242
interceptorManager.addInterceptor(DefaultRouterInterceptor(interceptor))
4343
}
@@ -81,9 +81,9 @@ class SchemeHandler(
8181
return configRequest { copy(exitAnim = exitAnim) }
8282
}
8383

84-
fun flow(): Flow<Unit> {
84+
fun flow(context: Context): Flow<Unit> {
8585
val handler = configRequest { copy(needResult = false) }
86-
return RouterCore.dispatchScheme(handler.request, handler.interceptorManager)
86+
return RouterCore.dispatchScheme(context, handler.request, handler.interceptorManager)
8787
.flatMapConcat {
8888
if (it.isSuccess) {
8989
flowOf(Unit)
@@ -93,43 +93,46 @@ class SchemeHandler(
9393
}
9494
}
9595

96-
fun resultFlow(): Flow<Result<Bundle>> {
96+
fun resultFlow(context: Context): Flow<Result<Bundle>> {
9797
val handler = configRequest { copy(needResult = true) }
98-
return RouterCore.dispatchScheme(handler.request, handler.interceptorManager)
98+
return RouterCore.dispatchScheme(context, handler.request, handler.interceptorManager)
9999
}
100100

101101
fun route(
102-
scope: CoroutineScope = InternalHelper.scope,
102+
context: Context,
103103
onError: (Throwable) -> Unit = {},
104+
onSuccess: () -> Unit = {},
104105
onResult: (Bundle) -> Unit = EMPTY_LAMBDA
105106
) {
106107
if (onResult == EMPTY_LAMBDA) {
107-
flow().catch { onError(it) }.launchIn(scope)
108+
flow(context).catch { onError(it) }
109+
.onCompletion { onSuccess() }
110+
.launchIn(context.findScope())
108111
} else {
109-
resultFlow().onEach {
110-
if (it.isSuccess) {
111-
onResult(it.getOrDefault(Bundle()))
112-
} else {
113-
onError(it.exceptionOrNull() ?: Throwable())
112+
resultFlow(context)
113+
.onEach {
114+
if (it.isSuccess) {
115+
onResult(it.getOrDefault(Bundle()))
116+
} else {
117+
onError(it.exceptionOrNull() ?: Throwable())
118+
}
114119
}
115-
}.launchIn(scope)
120+
.catch { onError(it) }
121+
.onCompletion { onSuccess() }
122+
.launchIn(context.findScope())
116123
}
117124
}
118125

119-
fun getLauncher(): SchemeLauncher {
126+
fun getLauncher(context: Context): SchemeLauncher {
120127
val schemeHandler = configRequest { copy(needResult = true) }
121128

122-
val activity = InternalHelper.fragmentActivity
123-
?: throw IllegalStateException("No FragmentActivity founded!")
124-
125-
if (activity.lifecycle.currentState != Lifecycle.State.INITIALIZED) {
126-
throw IllegalStateException("You must call getLauncher() after activity are created.")
127-
}
129+
val activity = context.findActivity()
130+
?: throw IllegalStateException("No Activity founded!")
128131

129132
val key = activity.key()
130133
var launcher = SchemeLauncherManager.getLauncher(key, request.scheme)
131134
if (launcher == null) {
132-
launcher = SchemeLauncher(schemeHandler.request, schemeHandler.interceptorManager)
135+
launcher = SchemeLauncher(context, schemeHandler.request, schemeHandler.interceptorManager)
133136
SchemeLauncherManager.addLauncher(key, launcher)
134137
}
135138

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package com.thoughtworks.ark.router
22

3+
import android.content.Context
34
import android.os.Bundle
4-
import androidx.lifecycle.lifecycleScope
5+
import com.thoughtworks.ark.router.internal.InternalHelper.findScope
56
import kotlinx.coroutines.flow.Flow
67
import kotlinx.coroutines.flow.MutableSharedFlow
78
import kotlinx.coroutines.flow.launchIn
8-
import com.thoughtworks.ark.router.internal.InternalHelper
9-
import com.thoughtworks.ark.router.internal.logw
109

1110
class SchemeLauncher(
11+
val context: Context,
1212
val schemeRequest: SchemeRequest,
1313
val interceptorManager: InterceptorManager
1414
) {
@@ -19,11 +19,7 @@ class SchemeLauncher(
1919
}
2020

2121
fun launch() {
22-
val activity = InternalHelper.fragmentActivity
23-
if (activity == null) {
24-
"No valid Activity found!".logw()
25-
return
26-
}
27-
RouterCore.dispatchScheme(schemeRequest, interceptorManager).launchIn(activity.lifecycleScope)
22+
RouterCore.dispatchScheme(context, schemeRequest, interceptorManager)
23+
.launchIn(context.findScope())
2824
}
2925
}

router/src/main/java/com/thoughtworks/ark/router/dispatcher/SchemeDispatcher.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
package com.thoughtworks.ark.router.dispatcher
22

3+
import android.content.Context
34
import android.os.Bundle
45
import androidx.fragment.app.DialogFragment
56
import androidx.fragment.app.Fragment
67
import androidx.fragment.app.FragmentActivity
7-
import kotlinx.coroutines.flow.Flow
8-
import kotlinx.coroutines.flow.flowOf
98
import com.thoughtworks.ark.router.Action
109
import com.thoughtworks.ark.router.SchemeRequest
1110
import com.thoughtworks.ark.router.backstack.BackStackEntryManager
1211
import com.thoughtworks.ark.router.compose.ComposeDispatcher
1312
import com.thoughtworks.ark.router.compose.SchemeComposable
1413
import com.thoughtworks.ark.router.group.GroupEntryManager
1514
import com.thoughtworks.ark.router.internal.InternalHelper
15+
import com.thoughtworks.ark.router.internal.InternalHelper.findFragmentActivity
1616
import com.thoughtworks.ark.router.internal.logw
17+
import kotlinx.coroutines.flow.Flow
18+
import kotlinx.coroutines.flow.flowOf
1719

1820
class SchemeDispatcher {
1921
private val dispatcherMaps = LinkedHashMap<Class<*>, InnerDispatcher>()
@@ -36,13 +38,13 @@ class SchemeDispatcher {
3638
}
3739
}
3840

39-
suspend fun dispatch(request: SchemeRequest): Flow<Result<Bundle>> {
41+
suspend fun dispatch(context: Context, request: SchemeRequest): Flow<Result<Bundle>> {
4042
if (request.className.isEmpty()) {
4143
"Scheme --> dispatch failed! Class not found!".logw()
4244
return flowOf(Result.failure(IllegalStateException("Scheme class not found!")))
4345
}
4446

45-
val fragmentActivity = InternalHelper.fragmentActivity
47+
val fragmentActivity = context.findFragmentActivity()
4648
return if (fragmentActivity == null) {
4749
findDispatcher(request).dispatch(InternalHelper.context, request)
4850
} else {

router/src/main/java/com/thoughtworks/ark/router/internal/InternalHelper.kt

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import android.app.Activity
44
import android.app.Activity.RESULT_OK
55
import android.app.Application
66
import android.content.Context
7+
import android.content.ContextWrapper
78
import android.content.Intent
89
import android.os.Bundle
910
import android.view.ViewGroup
1011
import androidx.fragment.app.FragmentActivity
11-
import androidx.lifecycle.LifecycleOwner
1212
import androidx.lifecycle.lifecycleScope
1313
import kotlinx.coroutines.CoroutineScope
1414
import kotlinx.coroutines.MainScope
@@ -37,19 +37,6 @@ object InternalHelper {
3737
}
3838
}
3939

40-
private val lifecycleOwner: LifecycleOwner?
41-
get() = with(activity) {
42-
if (this != null && this is LifecycleOwner) {
43-
this
44-
} else {
45-
null
46-
}
47-
}
48-
49-
internal val scope: CoroutineScope
50-
get() = lifecycleOwner?.lifecycleScope ?: internalScope
51-
52-
5340
fun Activity.setActivityResult(bundle: Bundle) {
5441
if (bundle.isEmpty) return
5542
setResult(RESULT_OK, Intent().apply { putExtras(bundle) })
@@ -58,4 +45,26 @@ object InternalHelper {
5845
fun Activity.contentView(): ViewGroup {
5946
return findViewById(android.R.id.content)
6047
}
48+
49+
fun Context.findActivity(): Activity? {
50+
var context = this
51+
while (context is ContextWrapper) {
52+
if (context is Activity) return context
53+
context = context.baseContext
54+
}
55+
return null
56+
}
57+
58+
fun Context.findFragmentActivity(): FragmentActivity? {
59+
val activity = findActivity()
60+
if (activity is FragmentActivity) {
61+
return activity
62+
}
63+
return null
64+
}
65+
66+
fun Context.findScope(): CoroutineScope {
67+
val fragmentActivity = findFragmentActivity()
68+
return fragmentActivity?.lifecycleScope ?: internalScope
69+
}
6170
}

0 commit comments

Comments
 (0)