Browse Source

新增作用域调度器选项, 统一catch/finally和scope调度器, 更新BRV

drake 4 years ago
parent
commit
d378f4baf5
53 changed files with 228 additions and 180 deletions
  1. 2 2
      README.md
  2. 1 1
      build.gradle
  3. 1 1
      docs/api/net/com.drake.net.scope/-android-scope/-init-.md
  4. 5 0
      docs/api/net/com.drake.net.scope/-android-scope/adjust-dispatcher.md
  5. 5 0
      docs/api/net/com.drake.net.scope/-android-scope/dispatcher.md
  6. 3 2
      docs/api/net/com.drake.net.scope/-android-scope/index.md
  7. 1 1
      docs/api/net/com.drake.net.scope/-dialog-coroutine-scope/-init-.md
  8. 1 1
      docs/api/net/com.drake.net.scope/-dialog-coroutine-scope/index.md
  9. 1 1
      docs/api/net/com.drake.net.scope/-net-coroutine-scope/-init-.md
  10. 4 3
      docs/api/net/com.drake.net.scope/-net-coroutine-scope/index.md
  11. 18 0
      docs/api/net/com.drake.net.scope/-net-coroutine-scope/preview.md
  12. 5 0
      docs/api/net/com.drake.net.scope/-net-coroutine-scope/start.md
  13. 1 1
      docs/api/net/com.drake.net.scope/-page-coroutine-scope/-init-.md
  14. 1 1
      docs/api/net/com.drake.net.scope/-page-coroutine-scope/index.md
  15. 1 1
      docs/api/net/com.drake.net.scope/-state-coroutine-scope/-init-.md
  16. 1 1
      docs/api/net/com.drake.net.scope/-state-coroutine-scope/index.md
  17. 1 1
      docs/api/net/com.drake.net.transform/-deferred-transform/-init-.md
  18. 1 1
      docs/api/net/com.drake.net.transform/-deferred-transform/block.md
  19. 3 3
      docs/api/net/com.drake.net.transform/-deferred-transform/index.md
  20. 1 1
      docs/api/net/com.drake.net.transform/index.md
  21. 1 1
      docs/api/net/com.drake.net.transform/kotlinx.coroutines.-deferred/index.md
  22. 1 1
      docs/api/net/com.drake.net.transform/kotlinx.coroutines.-deferred/transform.md
  23. 1 1
      docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment-activity/index.md
  24. 1 1
      docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment-activity/scope-dialog.md
  25. 3 3
      docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/index.md
  26. 1 1
      docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/scope-dialog.md
  27. 1 1
      docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/scope-life.md
  28. 1 1
      docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/scope-net-life.md
  29. 2 2
      docs/api/net/com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/index.md
  30. 1 1
      docs/api/net/com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-life.md
  31. 1 1
      docs/api/net/com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-net-life.md
  32. 1 1
      docs/api/net/com.drake.net.utils/com.drake.brv.-page-refresh-layout/index.md
  33. 1 1
      docs/api/net/com.drake.net.utils/com.drake.brv.-page-refresh-layout/scope.md
  34. 1 1
      docs/api/net/com.drake.net.utils/com.drake.statelayout.-state-layout/index.md
  35. 1 1
      docs/api/net/com.drake.net.utils/com.drake.statelayout.-state-layout/scope.md
  36. 2 2
      docs/api/net/com.drake.net.utils/index.md
  37. 2 2
      docs/api/net/com.drake.net.utils/kotlinx.coroutines.-coroutine-scope/fastest.md
  38. 1 1
      docs/api/net/com.drake.net.utils/kotlinx.coroutines.-coroutine-scope/index.md
  39. 2 2
      docs/api/net/com.drake.net.utils/kotlinx.coroutines.flow.-flow/index.md
  40. 2 2
      docs/api/net/com.drake.net.utils/kotlinx.coroutines.flow.-flow/listen.md
  41. 1 1
      docs/api/net/com.drake.net.utils/kotlinx.coroutines.flow.-flow/scope.md
  42. 1 1
      docs/api/net/com.drake.net.utils/scope-net.md
  43. 1 1
      docs/api/net/com.drake.net.utils/scope.md
  44. 12 12
      docs/api/net/package-list
  45. 2 4
      net/build.gradle
  46. 23 25
      net/src/main/java/com/drake/net/scope/AndroidScope.kt
  47. 5 2
      net/src/main/java/com/drake/net/scope/DialogCoroutineScope.kt
  48. 19 27
      net/src/main/java/com/drake/net/scope/NetCoroutineScope.kt
  49. 6 1
      net/src/main/java/com/drake/net/scope/PageCoroutineScope.kt
  50. 6 1
      net/src/main/java/com/drake/net/scope/StateCoroutineScope.kt
  51. 11 20
      net/src/main/java/com/drake/net/utils/JetPackUtils.kt
  52. 43 32
      net/src/main/java/com/drake/net/utils/ScopeUtils.kt
  53. 14 4
      sample/src/main/java/com/drake/net/sample/ui/fragment/RequestMethodFragment.kt

+ 2 - 2
README.md

@@ -105,9 +105,9 @@ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
 
 // 支持自动下拉刷新和缺省页的(可选)
-implementation 'com.github.liangjingkanji:BRV:1.3.8'
+implementation 'com.github.liangjingkanji:BRV:1.3.9'
 
-implementation 'com.github.liangjingkanji:Net:2.2.13'
+implementation 'com.github.liangjingkanji:Net:2.2.14'
 ```
 
 <br>

+ 1 - 1
build.gradle

@@ -19,7 +19,7 @@
 buildscript {
     ext {
         kotlin_version = '1.4.0'
-        brv_version = '1.3.8'
+        brv_version = '1.3.9'
         coroutine_version = '1.3.7'
         glide_version = '4.9.0'
         room_version = "2.2.5"

+ 1 - 1
docs/api/net/com.drake.net.scope/-android-scope/-init-.md

@@ -2,7 +2,7 @@
 
 # &lt;init&gt;
 
-`AndroidScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY)`
+`AndroidScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)`
 
 异步协程作用域
 

+ 5 - 0
docs/api/net/com.drake.net.scope/-android-scope/adjust-dispatcher.md

@@ -0,0 +1,5 @@
+[net](../../index.md) / [com.drake.net.scope](../index.md) / [AndroidScope](index.md) / [adjustDispatcher](./adjust-dispatcher.md)
+
+# adjustDispatcher
+
+`protected fun adjustDispatcher(): CoroutineDispatcher`

+ 5 - 0
docs/api/net/com.drake.net.scope/-android-scope/dispatcher.md

@@ -0,0 +1,5 @@
+[net](../../index.md) / [com.drake.net.scope](../index.md) / [AndroidScope](index.md) / [dispatcher](./dispatcher.md)
+
+# dispatcher
+
+`val dispatcher: CoroutineDispatcher`

+ 3 - 2
docs/api/net/com.drake.net.scope/-android-scope/index.md

@@ -10,7 +10,7 @@
 
 | Name | Summary |
 |---|---|
-| [&lt;init&gt;](-init-.md) | 异步协程作用域`AndroidScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY)` |
+| [&lt;init&gt;](-init-.md) | 异步协程作用域`AndroidScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)` |
 
 ### Properties
 
@@ -18,6 +18,7 @@
 |---|---|
 | [catch](catch.md) | `var catch: (`[`AndroidScope`](./index.md)`.(`[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`)?` |
 | [coroutineContext](coroutine-context.md) | `open val coroutineContext: `[`CoroutineContext`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/-coroutine-context/index.html) |
+| [dispatcher](dispatcher.md) | `val dispatcher: CoroutineDispatcher` |
 | [finally](finally.md) | `var finally: (`[`AndroidScope`](./index.md)`.(`[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`?) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`)?` |
 | [uid](uid.md) | `val uid: CoroutineExceptionHandler` |
 
@@ -25,12 +26,12 @@
 
 | Name | Summary |
 |---|---|
+| [adjustDispatcher](adjust-dispatcher.md) | `fun adjustDispatcher(): CoroutineDispatcher` |
 | [cancel](cancel.md) | `open fun cancel(cause: CancellationException? = null): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)<br>`open fun cancel(message: `[`String`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/index.html)`, cause: `[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`? = null): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 | [catch](catch.md) | `open fun catch(e: `[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)<br>当作用域内发生异常时回调`open fun catch(block: `[`AndroidScope`](./index.md)`.(`[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)` = {}): `[`AndroidScope`](./index.md) |
 | [finally](finally.md) | `open fun finally(e: `[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`?): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)<br>无论正常或者异常结束都将最终执行`open fun finally(block: `[`AndroidScope`](./index.md)`.(`[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`?) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)` = {}): `[`AndroidScope`](./index.md) |
 | [handleError](handle-error.md) | 错误处理`open fun handleError(e: `[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 | [launch](launch.md) | `open fun launch(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](./index.md) |
-| [start](start.md) | `open fun start(): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 
 ### Inheritors
 

+ 1 - 1
docs/api/net/com.drake.net.scope/-dialog-coroutine-scope/-init-.md

@@ -2,7 +2,7 @@
 
 # &lt;init&gt;
 
-`DialogCoroutineScope(activity: FragmentActivity, dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true)`
+`DialogCoroutineScope(activity: FragmentActivity, dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, dispatcher: CoroutineDispatcher = Dispatchers.Main)`
 
 自动加载对话框网络请求
 

+ 1 - 1
docs/api/net/com.drake.net.scope/-dialog-coroutine-scope/index.md

@@ -22,7 +22,7 @@
 
 | Name | Summary |
 |---|---|
-| [&lt;init&gt;](-init-.md) | 自动加载对话框网络请求`DialogCoroutineScope(activity: FragmentActivity, dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true)` |
+| [&lt;init&gt;](-init-.md) | 自动加载对话框网络请求`DialogCoroutineScope(activity: FragmentActivity, dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, dispatcher: CoroutineDispatcher = Dispatchers.Main)` |
 
 ### Properties
 

+ 1 - 1
docs/api/net/com.drake.net.scope/-net-coroutine-scope/-init-.md

@@ -2,7 +2,7 @@
 
 # &lt;init&gt;
 
-`NetCoroutineScope(lifecycleOwner: LifecycleOwner, lifeEvent: Event = Lifecycle.Event.ON_DESTROY)``NetCoroutineScope()`
+`NetCoroutineScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)`
 
 自动显示网络错误信息协程作用域
 

+ 4 - 3
docs/api/net/com.drake.net.scope/-net-coroutine-scope/index.md

@@ -10,7 +10,7 @@
 
 | Name | Summary |
 |---|---|
-| [&lt;init&gt;](-init-.md) | `NetCoroutineScope(lifecycleOwner: LifecycleOwner, lifeEvent: Event = Lifecycle.Event.ON_DESTROY)`<br>自动显示网络错误信息协程作用域`NetCoroutineScope()` |
+| [&lt;init&gt;](-init-.md) | 自动显示网络错误信息协程作用域`NetCoroutineScope(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main)` |
 
 ### Properties
 
@@ -20,19 +20,20 @@
 | [error](error.md) | `var error: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) |
 | [isCacheSucceed](is-cache-succeed.md) | `var isCacheSucceed: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) |
 | [isReadCache](is-read-cache.md) | `var isReadCache: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html) |
-| [onCache](on-cache.md) | `var onCache: (suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`)?` |
+| [preview](preview.md) | `var preview: (suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`)?` |
 
 ### Functions
 
 | Name | Summary |
 |---|---|
-| [cache](cache.md) | 该函数一般用于缓存读取 只在第一次启动作用域时回调 该函数在作用域[launch](launch.md)之前执行 函数内部所有的异常都不会被抛出, 也不会终止作用域执行`fun cache(error: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = false, animate: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = false, onCache: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../-android-scope/index.md) |
 | [cancel](cancel.md) | `open fun cancel(cause: CancellationException?): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 | [catch](catch.md) | `open fun catch(e: `[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 | [finally](finally.md) | `open fun finally(e: `[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`?): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 | [handleError](handle-error.md) | 错误处理`open fun handleError(e: `[`Throwable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 | [launch](launch.md) | `open fun launch(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](./index.md) |
+| [preview](preview.md) | "预览"作用域 该函数一般用于缓存读取, 只在第一次启动作用域时回调 该函数在作用域[NetCoroutineScope.launch](launch.md)之前执行 函数内部所有的异常都不会被抛出, 也不会终止作用域执行`fun preview(ignore: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = false, animate: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = false, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../-android-scope/index.md) |
 | [readCache](read-cache.md) | 读取缓存回调`open fun readCache(succeed: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
+| [start](start.md) | `open fun start(): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
 
 ### Inheritors
 

+ 18 - 0
docs/api/net/com.drake.net.scope/-net-coroutine-scope/preview.md

@@ -0,0 +1,18 @@
+[net](../../index.md) / [com.drake.net.scope](../index.md) / [NetCoroutineScope](index.md) / [preview](./preview.md)
+
+# preview
+
+`protected var preview: (suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`)?``fun preview(ignore: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = false, animate: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = false, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../-android-scope/index.md)
+
+"预览"作用域
+该函数一般用于缓存读取, 只在第一次启动作用域时回调
+该函数在作用域[NetCoroutineScope.launch](launch.md)之前执行
+函数内部所有的异常都不会被抛出, 也不会终止作用域执行
+
+### Parameters
+
+`ignore` - 是否在缓存读取成功但网络请求错误时吐司错误信息
+
+`animate` - 是否在缓存成功后依然显示加载动画
+
+`block` - 该作用域内的所有异常都算缓存读取失败, 不会吐司和打印任何错误

+ 5 - 0
docs/api/net/com.drake.net.scope/-net-coroutine-scope/start.md

@@ -0,0 +1,5 @@
+[net](../../index.md) / [com.drake.net.scope](../index.md) / [NetCoroutineScope](index.md) / [start](./start.md)
+
+# start
+
+`protected open fun start(): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)

+ 1 - 1
docs/api/net/com.drake.net.scope/-page-coroutine-scope/-init-.md

@@ -2,4 +2,4 @@
 
 # &lt;init&gt;
 
-`PageCoroutineScope(page: PageRefreshLayout)`
+`PageCoroutineScope(page: PageRefreshLayout, dispatcher: CoroutineDispatcher = Dispatchers.Main)`

+ 1 - 1
docs/api/net/com.drake.net.scope/-page-coroutine-scope/index.md

@@ -8,7 +8,7 @@
 
 | Name | Summary |
 |---|---|
-| [&lt;init&gt;](-init-.md) | `PageCoroutineScope(page: PageRefreshLayout)` |
+| [&lt;init&gt;](-init-.md) | `PageCoroutineScope(page: PageRefreshLayout, dispatcher: CoroutineDispatcher = Dispatchers.Main)` |
 
 ### Properties
 

+ 1 - 1
docs/api/net/com.drake.net.scope/-state-coroutine-scope/-init-.md

@@ -2,7 +2,7 @@
 
 # &lt;init&gt;
 
-`StateCoroutineScope(state: StateLayout)`
+`StateCoroutineScope(state: StateLayout, dispatcher: CoroutineDispatcher = Dispatchers.Main)`
 
 缺省页作用域
 

+ 1 - 1
docs/api/net/com.drake.net.scope/-state-coroutine-scope/index.md

@@ -10,7 +10,7 @@
 
 | Name | Summary |
 |---|---|
-| [&lt;init&gt;](-init-.md) | 缺省页作用域`StateCoroutineScope(state: StateLayout)` |
+| [&lt;init&gt;](-init-.md) | 缺省页作用域`StateCoroutineScope(state: StateLayout, dispatcher: CoroutineDispatcher = Dispatchers.Main)` |
 
 ### Properties
 

+ 1 - 1
docs/api/net/com.drake.net.transform/-deferred-transform/-init-.md

@@ -2,4 +2,4 @@
 
 # &lt;init&gt;
 
-`DeferredTransform(deferred: Deferred<T>, block: (T) -> T = { it })`
+`DeferredTransform(deferred: Deferred<T>, block: (T) -> R)`

+ 1 - 1
docs/api/net/com.drake.net.transform/-deferred-transform/block.md

@@ -2,4 +2,4 @@
 
 # block
 
-`val block: (T) -> T`
+`val block: (T) -> R`

+ 3 - 3
docs/api/net/com.drake.net.transform/-deferred-transform/index.md

@@ -2,17 +2,17 @@
 
 # DeferredTransform
 
-`data class DeferredTransform<T>`
+`data class DeferredTransform<T, R>`
 
 ### Constructors
 
 | Name | Summary |
 |---|---|
-| [&lt;init&gt;](-init-.md) | `DeferredTransform(deferred: Deferred<T>, block: (T) -> T = { it })` |
+| [&lt;init&gt;](-init-.md) | `DeferredTransform(deferred: Deferred<T>, block: (T) -> R)` |
 
 ### Properties
 
 | Name | Summary |
 |---|---|
-| [block](block.md) | `val block: (T) -> T` |
+| [block](block.md) | `val block: (T) -> R` |
 | [deferred](deferred.md) | `val deferred: Deferred<T>` |

+ 1 - 1
docs/api/net/com.drake.net.transform/index.md

@@ -6,7 +6,7 @@
 
 | Name | Summary |
 |---|---|
-| [DeferredTransform](-deferred-transform/index.md) | `data class DeferredTransform<T>` |
+| [DeferredTransform](-deferred-transform/index.md) | `data class DeferredTransform<T, R>` |
 
 ### Extensions for External Classes
 

+ 1 - 1
docs/api/net/com.drake.net.transform/kotlinx.coroutines.-deferred/index.md

@@ -4,4 +4,4 @@
 
 | Name | Summary |
 |---|---|
-| [transform](transform.md) | `fun <T> Deferred<T>.transform(block: (T) -> T): `[`DeferredTransform`](../-deferred-transform/index.md)`<T>` |
+| [transform](transform.md) | `fun <T, R> Deferred<T>.transform(block: (T) -> R): `[`DeferredTransform`](../-deferred-transform/index.md)`<T, R>` |

+ 1 - 1
docs/api/net/com.drake.net.transform/kotlinx.coroutines.-deferred/transform.md

@@ -2,4 +2,4 @@
 
 # transform
 
-`fun <T> Deferred<T>.transform(block: (T) -> T): `[`DeferredTransform`](../-deferred-transform/index.md)`<T>`
+`fun <T, R> Deferred<T>.transform(block: (T) -> R): `[`DeferredTransform`](../-deferred-transform/index.md)`<T, R>`

+ 1 - 1
docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment-activity/index.md

@@ -5,4 +5,4 @@
 | Name | Summary |
 |---|---|
 | [getSavedModel](get-saved-model.md) | 返回当前组件指定的SavedViewModel`fun <M : ViewModel> FragmentActivity.getSavedModel(): M` |
-| [scopeDialog](scope-dialog.md) | 作用域开始时自动显示加载对话框, 结束时自动关闭加载对话框 可以设置全局对话框 [com.drake.net.NetConfig.onDialog](../../com.drake.net/-net-config/on-dialog.md)`fun FragmentActivity.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |
+| [scopeDialog](scope-dialog.md) | 作用域开始时自动显示加载对话框, 结束时自动关闭加载对话框 可以设置全局对话框 [com.drake.net.NetConfig.onDialog](../../com.drake.net/-net-config/on-dialog.md)`fun FragmentActivity.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |

+ 1 - 1
docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment-activity/scope-dialog.md

@@ -2,7 +2,7 @@
 
 # scopeDialog
 
-`fun FragmentActivity.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
+`fun FragmentActivity.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
 
 作用域开始时自动显示加载对话框, 结束时自动关闭加载对话框
 可以设置全局对话框 [com.drake.net.NetConfig.onDialog](../../com.drake.net/-net-config/on-dialog.md)

+ 3 - 3
docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/index.md

@@ -5,6 +5,6 @@
 | Name | Summary |
 |---|---|
 | [getSavedModel](get-saved-model.md) | 返回当前组件指定的SavedViewModel`fun <M : ViewModel> Fragment.getSavedModel(): M` |
-| [scopeDialog](scope-dialog.md) | `fun Fragment.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |
-| [scopeLife](scope-life.md) | `fun Fragment.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md) |
-| [scopeNetLife](scope-net-life.md) | Fragment应当在[Lifecycle.Event.ON_STOP](#)时就取消作用域, 避免[Fragment.onDestroyView](#)导致引用空视图`fun Fragment.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |
+| [scopeDialog](scope-dialog.md) | `fun Fragment.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |
+| [scopeLife](scope-life.md) | `fun Fragment.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md) |
+| [scopeNetLife](scope-net-life.md) | Fragment应当在[Lifecycle.Event.ON_STOP](#)时就取消作用域, 避免[Fragment.onDestroyView](#)导致引用空视图`fun Fragment.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |

+ 1 - 1
docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/scope-dialog.md

@@ -2,4 +2,4 @@
 
 # scopeDialog
 
-`fun Fragment.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
+`fun Fragment.scopeDialog(dialog: `[`Dialog`](https://developer.android.com/reference/android/app/Dialog.html)`? = null, cancelable: `[`Boolean`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-boolean/index.html)` = true, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)

+ 1 - 1
docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/scope-life.md

@@ -2,4 +2,4 @@
 
 # scopeLife
 
-`fun Fragment.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md)
+`fun Fragment.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md)

+ 1 - 1
docs/api/net/com.drake.net.utils/androidx.fragment.app.-fragment/scope-net-life.md

@@ -2,7 +2,7 @@
 
 # scopeNetLife
 
-`fun Fragment.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
+`fun Fragment.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_STOP, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
 
 Fragment应当在[Lifecycle.Event.ON_STOP](#)时就取消作用域, 避免[Fragment.onDestroyView](#)导致引用空视图
 

+ 2 - 2
docs/api/net/com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/index.md

@@ -5,5 +5,5 @@
 | Name | Summary |
 |---|---|
 | [observe](observe.md) | 快速创建LiveData的观察者`fun <M> LifecycleOwner.observe(liveData: LiveData<M>?, block: M?.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
-| [scopeLife](scope-life.md) | `fun LifecycleOwner.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md) |
-| [scopeNetLife](scope-net-life.md) | `fun LifecycleOwner.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |
+| [scopeLife](scope-life.md) | `fun LifecycleOwner.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md) |
+| [scopeNetLife](scope-net-life.md) | `fun LifecycleOwner.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |

+ 1 - 1
docs/api/net/com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-life.md

@@ -2,4 +2,4 @@
 
 # scopeLife
 
-`fun LifecycleOwner.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md)
+`fun LifecycleOwner.scopeLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md)

+ 1 - 1
docs/api/net/com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-net-life.md

@@ -2,4 +2,4 @@
 
 # scopeNetLife
 
-`fun LifecycleOwner.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
+`fun LifecycleOwner.scopeNetLife(lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)

+ 1 - 1
docs/api/net/com.drake.net.utils/com.drake.brv.-page-refresh-layout/index.md

@@ -4,4 +4,4 @@
 
 | Name | Summary |
 |---|---|
-| [scope](scope.md) | PageRefreshLayout的异步作用域`fun PageRefreshLayout.scope(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`PageCoroutineScope`](../../com.drake.net.scope/-page-coroutine-scope/index.md) |
+| [scope](scope.md) | PageRefreshLayout的异步作用域`fun PageRefreshLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`PageCoroutineScope`](../../com.drake.net.scope/-page-coroutine-scope/index.md) |

+ 1 - 1
docs/api/net/com.drake.net.utils/com.drake.brv.-page-refresh-layout/scope.md

@@ -2,7 +2,7 @@
 
 # scope
 
-`fun PageRefreshLayout.scope(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`PageCoroutineScope`](../../com.drake.net.scope/-page-coroutine-scope/index.md)
+`fun PageRefreshLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`PageCoroutineScope`](../../com.drake.net.scope/-page-coroutine-scope/index.md)
 
 PageRefreshLayout的异步作用域
 

+ 1 - 1
docs/api/net/com.drake.net.utils/com.drake.statelayout.-state-layout/index.md

@@ -4,4 +4,4 @@
 
 | Name | Summary |
 |---|---|
-| [scope](scope.md) | 自动处理缺省页的异步作用域 作用域开始执行时显示加载中缺省页 作用域正常结束时显示成功缺省页 作用域抛出异常时显示错误缺省页 并且自动吐司错误信息, 可配置 [com.drake.net.NetConfig.onStateError](../../com.drake.net/-net-config/on-state-error.md) 自动打印异常日志`fun StateLayout.scope(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |
+| [scope](scope.md) | 自动处理缺省页的异步作用域 作用域开始执行时显示加载中缺省页 作用域正常结束时显示成功缺省页 作用域抛出异常时显示错误缺省页 并且自动吐司错误信息, 可配置 [com.drake.net.NetConfig.onStateError](../../com.drake.net/-net-config/on-state-error.md) 自动打印异常日志`fun StateLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md) |

+ 1 - 1
docs/api/net/com.drake.net.utils/com.drake.statelayout.-state-layout/scope.md

@@ -2,7 +2,7 @@
 
 # scope
 
-`fun StateLayout.scope(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
+`fun StateLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../../com.drake.net.scope/-net-coroutine-scope/index.md)
 
 自动处理缺省页的异步作用域
 作用域开始执行时显示加载中缺省页

+ 2 - 2
docs/api/net/com.drake.net.utils/index.md

@@ -27,8 +27,8 @@
 | Name | Summary |
 |---|---|
 | [runMain](run-main.md) | 在主线程运行`fun runMain(block: () -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
-| [scope](scope.md) | 异步作用域`fun scope(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../com.drake.net.scope/-android-scope/index.md) |
-| [scopeNet](scope-net.md) | 网络请求的异步作用域 自动显示错误信息吐司`fun scopeNet(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../com.drake.net.scope/-net-coroutine-scope/index.md) |
+| [scope](scope.md) | 异步作用域`fun scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../com.drake.net.scope/-android-scope/index.md) |
+| [scopeNet](scope-net.md) | 网络请求的异步作用域 自动显示错误信息吐司`fun scopeNet(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../com.drake.net.scope/-net-coroutine-scope/index.md) |
 | [withDefault](with-default.md) | 切换到默认调度器`suspend fun <T> withDefault(block: suspend CoroutineScope.() -> T): T` |
 | [withIO](with-i-o.md) | 切换到IO程调度器`suspend fun <T> withIO(block: suspend CoroutineScope.() -> T): T` |
 | [withMain](with-main.md) | 切换到主线程调度器`suspend fun <T> withMain(block: suspend CoroutineScope.() -> T): T` |

+ 2 - 2
docs/api/net/com.drake.net.utils/kotlinx.coroutines.-coroutine-scope/fastest.md

@@ -9,9 +9,9 @@
 
 ### Parameters
 
-`deferredArray` - 一系列并发任务`suspend fun <T> CoroutineScope.fastest(vararg deferredArray: `[`DeferredTransform`](../../com.drake.net.transform/-deferred-transform/index.md)`<T>): T`
+`deferredArray` - 一系列并发任务`suspend fun <T, R> CoroutineScope.fastest(vararg deferredArray: `[`DeferredTransform`](../../com.drake.net.transform/-deferred-transform/index.md)`<T, R>): R`
 
-该函数将选择[deferredArray](fastest.md#com.drake.net.utils$fastest(kotlinx.coroutines.CoroutineScope, kotlin.Array((com.drake.net.transform.DeferredTransform((com.drake.net.utils.fastest.T)))))/deferredArray)中的Deferred执行[Deferred.await](#), 然后将返回最快的结果
+该函数将选择[deferredArray](fastest.md#com.drake.net.utils$fastest(kotlinx.coroutines.CoroutineScope, kotlin.Array((com.drake.net.transform.DeferredTransform((com.drake.net.utils.fastest.T, com.drake.net.utils.fastest.R)))))/deferredArray)中的Deferred执行[Deferred.await](#), 然后将返回最快的结果
 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常
 
 ### Parameters

+ 1 - 1
docs/api/net/com.drake.net.utils/kotlinx.coroutines.-coroutine-scope/index.md

@@ -4,4 +4,4 @@
 
 | Name | Summary |
 |---|---|
-| [fastest](fastest.md) | 该函数将选择[deferredArray](fastest.md#com.drake.net.utils$fastest(kotlinx.coroutines.CoroutineScope, kotlin.Array((kotlinx.coroutines.Deferred((com.drake.net.utils.fastest.T)))))/deferredArray)中的Deferred执行[Deferred.await](#), 然后将返回最快的结果 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常`suspend fun <T> CoroutineScope.fastest(vararg deferredArray: Deferred<T>): T`<br>`suspend fun <T> CoroutineScope.fastest(vararg deferredArray: `[`DeferredTransform`](../../com.drake.net.transform/-deferred-transform/index.md)`<T>): T` |
+| [fastest](fastest.md) | 该函数将选择[deferredArray](fastest.md#com.drake.net.utils$fastest(kotlinx.coroutines.CoroutineScope, kotlin.Array((kotlinx.coroutines.Deferred((com.drake.net.utils.fastest.T)))))/deferredArray)中的Deferred执行[Deferred.await](#), 然后将返回最快的结果 执行过程中的异常将被忽略, 如果全部抛出异常则将抛出最后一个Deferred的异常`suspend fun <T> CoroutineScope.fastest(vararg deferredArray: Deferred<T>): T`<br>`suspend fun <T, R> CoroutineScope.fastest(vararg deferredArray: `[`DeferredTransform`](../../com.drake.net.transform/-deferred-transform/index.md)`<T, R>): R` |

+ 2 - 2
docs/api/net/com.drake.net.utils/kotlinx.coroutines.flow.-flow/index.md

@@ -4,5 +4,5 @@
 
 | Name | Summary |
 |---|---|
-| [listen](listen.md) | 监听数据库`fun <T> Flow<`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>>.listen(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, block: (`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html) |
-| [scope](scope.md) | `fun <T> Flow<T>.scope(owner: LifecycleOwner? = null, event: Event = Lifecycle.Event.ON_DESTROY, action: suspend (value: T) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): CoroutineScope` |
+| [listen](listen.md) | 收集Flow结果并过滤重复结果`fun <T> Flow<`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>>.listen(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: (`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md) |
+| [scope](scope.md) | `fun <T> Flow<T>.scope(owner: LifecycleOwner? = null, event: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, action: suspend (value: T) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md) |

+ 2 - 2
docs/api/net/com.drake.net.utils/kotlinx.coroutines.flow.-flow/listen.md

@@ -2,7 +2,7 @@
 
 # listen
 
-`fun <T> Flow<`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>>.listen(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, block: (`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)
+`fun <T> Flow<`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>>.listen(lifecycleOwner: LifecycleOwner? = null, lifeEvent: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: (`[`List`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html)`<T>) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md)
 
-监听数据库
+收集Flow结果并过滤重复结果
 

+ 1 - 1
docs/api/net/com.drake.net.utils/kotlinx.coroutines.flow.-flow/scope.md

@@ -2,4 +2,4 @@
 
 # scope
 
-`inline fun <T> Flow<T>.scope(owner: LifecycleOwner? = null, event: Event = Lifecycle.Event.ON_DESTROY, crossinline action: suspend (value: T) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): CoroutineScope`
+`inline fun <T> Flow<T>.scope(owner: LifecycleOwner? = null, event: Event = Lifecycle.Event.ON_DESTROY, dispatcher: CoroutineDispatcher = Dispatchers.Main, crossinline action: suspend (value: T) -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../../com.drake.net.scope/-android-scope/index.md)

+ 1 - 1
docs/api/net/com.drake.net.utils/scope-net.md

@@ -2,7 +2,7 @@
 
 # scopeNet
 
-`fun scopeNet(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../com.drake.net.scope/-net-coroutine-scope/index.md)
+`fun scopeNet(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`NetCoroutineScope`](../com.drake.net.scope/-net-coroutine-scope/index.md)
 
 网络请求的异步作用域
 自动显示错误信息吐司

+ 1 - 1
docs/api/net/com.drake.net.utils/scope.md

@@ -2,7 +2,7 @@
 
 # scope
 
-`fun scope(block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../com.drake.net.scope/-android-scope/index.md)
+`fun scope(dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend CoroutineScope.() -> `[`Unit`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-unit/index.html)`): `[`AndroidScope`](../com.drake.net.scope/-android-scope/index.md)
 
 异步作用域
 

+ 12 - 12
docs/api/net/package-list

@@ -18,24 +18,24 @@ $dokka.location:com.drake.net$onError(com.yanzhenjie.kalle.KalleConfig.Builder,
 $dokka.location:com.drake.net$onStateError(com.yanzhenjie.kalle.KalleConfig.Builder, kotlin.Function2((kotlin.Throwable, android.view.View, kotlin.Unit)))com.drake.net/com.yanzhenjie.kalle.-kalle-config.-builder/on-state-error.md
 $dokka.location:com.drake.net$syncDownloadImage(android.content.Context, kotlin.String, kotlin.Int, kotlin.Int)com.drake.net/android.content.-context/sync-download-image.md
 $dokka.location:com.drake.net.error$NetCancellationException(kotlinx.coroutines.CoroutineScope, kotlin.String)com.drake.net.error/kotlinx.coroutines.-coroutine-scope/-net-cancellation-exception.md
-$dokka.location:com.drake.net.transform$transform(kotlinx.coroutines.Deferred((com.drake.net.transform.transform.T)), kotlin.Function1((com.drake.net.transform.transform.T, )))com.drake.net.transform/kotlinx.coroutines.-deferred/transform.md
-$dokka.location:com.drake.net.utils$fastest(kotlinx.coroutines.CoroutineScope, kotlin.Array((com.drake.net.transform.DeferredTransform((com.drake.net.utils.fastest.T)))))com.drake.net.utils/kotlinx.coroutines.-coroutine-scope/fastest.md
+$dokka.location:com.drake.net.transform$transform(kotlinx.coroutines.Deferred((com.drake.net.transform.transform.T)), kotlin.Function1((com.drake.net.transform.transform.T, com.drake.net.transform.transform.R)))com.drake.net.transform/kotlinx.coroutines.-deferred/transform.md
+$dokka.location:com.drake.net.utils$fastest(kotlinx.coroutines.CoroutineScope, kotlin.Array((com.drake.net.transform.DeferredTransform((com.drake.net.utils.fastest.T, com.drake.net.utils.fastest.R)))))com.drake.net.utils/kotlinx.coroutines.-coroutine-scope/fastest.md
 $dokka.location:com.drake.net.utils$fastest(kotlinx.coroutines.CoroutineScope, kotlin.Array((kotlinx.coroutines.Deferred((com.drake.net.utils.fastest.T)))))com.drake.net.utils/kotlinx.coroutines.-coroutine-scope/fastest.md
 $dokka.location:com.drake.net.utils$foreach(android.database.Cursor, kotlin.Function1((android.database.Cursor, kotlin.Unit)))com.drake.net.utils/android.database.-cursor/foreach.md
 $dokka.location:com.drake.net.utils$getSavedModel(androidx.fragment.app.Fragment)com.drake.net.utils/androidx.fragment.app.-fragment/get-saved-model.md
 $dokka.location:com.drake.net.utils$getSavedModel(androidx.fragment.app.FragmentActivity)com.drake.net.utils/androidx.fragment.app.-fragment-activity/get-saved-model.md
 $dokka.location:com.drake.net.utils$getViewModel(androidx.lifecycle.ViewModelStoreOwner)com.drake.net.utils/androidx.lifecycle.-view-model-store-owner/get-view-model.md
-$dokka.location:com.drake.net.utils$listen(kotlinx.coroutines.flow.Flow((kotlin.collections.List((com.drake.net.utils.listen.T)))), androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlin.Function1((kotlin.collections.List((com.drake.net.utils.listen.T)), kotlin.Unit)))com.drake.net.utils/kotlinx.coroutines.flow.-flow/listen.md
+$dokka.location:com.drake.net.utils$listen(kotlinx.coroutines.flow.Flow((kotlin.collections.List((com.drake.net.utils.listen.T)))), androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlinx.coroutines.CoroutineDispatcher, kotlin.Function1((kotlin.collections.List((com.drake.net.utils.listen.T)), kotlin.Unit)))com.drake.net.utils/kotlinx.coroutines.flow.-flow/listen.md
 $dokka.location:com.drake.net.utils$observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.LiveData((com.drake.net.utils.observe.M)), kotlin.Function1((com.drake.net.utils.observe.M, kotlin.Unit)))com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/observe.md
-$dokka.location:com.drake.net.utils$scope(com.drake.brv.PageRefreshLayout, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/com.drake.brv.-page-refresh-layout/scope.md
-$dokka.location:com.drake.net.utils$scope(com.drake.statelayout.StateLayout, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/com.drake.statelayout.-state-layout/scope.md
-$dokka.location:com.drake.net.utils$scope(kotlinx.coroutines.flow.Flow((com.drake.net.utils.scope.T)), androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlin.coroutines.SuspendFunction1((com.drake.net.utils.scope.T, kotlin.Unit)))com.drake.net.utils/kotlinx.coroutines.flow.-flow/scope.md
-$dokka.location:com.drake.net.utils$scopeDialog(androidx.fragment.app.Fragment, android.app.Dialog, kotlin.Boolean, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment/scope-dialog.md
-$dokka.location:com.drake.net.utils$scopeDialog(androidx.fragment.app.FragmentActivity, android.app.Dialog, kotlin.Boolean, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment-activity/scope-dialog.md
-$dokka.location:com.drake.net.utils$scopeLife(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.Event, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment/scope-life.md
-$dokka.location:com.drake.net.utils$scopeLife(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-life.md
-$dokka.location:com.drake.net.utils$scopeNetLife(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.Event, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment/scope-net-life.md
-$dokka.location:com.drake.net.utils$scopeNetLife(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-net-life.md
+$dokka.location:com.drake.net.utils$scope(com.drake.brv.PageRefreshLayout, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/com.drake.brv.-page-refresh-layout/scope.md
+$dokka.location:com.drake.net.utils$scope(com.drake.statelayout.StateLayout, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/com.drake.statelayout.-state-layout/scope.md
+$dokka.location:com.drake.net.utils$scope(kotlinx.coroutines.flow.Flow((com.drake.net.utils.scope.T)), androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((com.drake.net.utils.scope.T, kotlin.Unit)))com.drake.net.utils/kotlinx.coroutines.flow.-flow/scope.md
+$dokka.location:com.drake.net.utils$scopeDialog(androidx.fragment.app.Fragment, android.app.Dialog, kotlin.Boolean, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment/scope-dialog.md
+$dokka.location:com.drake.net.utils$scopeDialog(androidx.fragment.app.FragmentActivity, android.app.Dialog, kotlin.Boolean, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment-activity/scope-dialog.md
+$dokka.location:com.drake.net.utils$scopeLife(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.Event, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment/scope-life.md
+$dokka.location:com.drake.net.utils$scopeLife(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-life.md
+$dokka.location:com.drake.net.utils$scopeNetLife(androidx.fragment.app.Fragment, androidx.lifecycle.Lifecycle.Event, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.fragment.app.-fragment/scope-net-life.md
+$dokka.location:com.drake.net.utils$scopeNetLife(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Lifecycle.Event, kotlinx.coroutines.CoroutineDispatcher, kotlin.coroutines.SuspendFunction1((kotlinx.coroutines.CoroutineScope, kotlin.Unit)))com.drake.net.utils/androidx.lifecycle.-lifecycle-owner/scope-net-life.md
 com.drake.net
 com.drake.net.convert
 com.drake.net.error

+ 2 - 4
net/build.gradle

@@ -61,15 +61,13 @@ dependencies {
     androidTestImplementation "androidx.test:runner:1.3.0"
     androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0"
 
-
-    api project(path: ':kalle')
-
     implementation "com.github.liangjingkanji:Tooltip:1.0.4"
+    api project(path: ':kalle')
 
+    api 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
     compileOnly "com.github.liangjingkanji:BRV:$brv_version"
     compileOnly "com.github.bumptech.glide:glide:$glide_version"
 
-    api 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.2.0'
 
     compileOnly "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutine_version"
     compileOnly "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version"

+ 23 - 25
net/src/main/java/com/drake/net/scope/AndroidScope.kt

@@ -27,17 +27,14 @@ import kotlin.coroutines.EmptyCoroutineContext
  * 异步协程作用域
  */
 @Suppress("unused", "MemberVisibilityCanBePrivate", "NAME_SHADOWING")
-open class AndroidScope(
-    lifecycleOwner: LifecycleOwner? = null,
-    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY
-) : CoroutineScope {
+open class AndroidScope(lifecycleOwner: LifecycleOwner? = null,
+                        lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
+                        val dispatcher: CoroutineDispatcher = Dispatchers.Main) : CoroutineScope {
 
     init {
         lifecycleOwner?.lifecycle?.addObserver(object : LifecycleEventObserver {
             override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
-                if (lifeEvent == event) {
-                    cancel()
-                }
+                if (lifeEvent == event) cancel()
             }
         })
     }
@@ -50,33 +47,36 @@ open class AndroidScope(
 
     val uid = exceptionHandler
 
-    override val coroutineContext: CoroutineContext =
-        Dispatchers.Main + exceptionHandler + SupervisorJob()
+    override val coroutineContext: CoroutineContext = dispatcher + exceptionHandler + SupervisorJob()
 
 
-    open fun launch(
-        block: suspend CoroutineScope.() -> Unit
-    ): AndroidScope {
-        start()
-        launch(EmptyCoroutineContext, block = block).invokeOnCompletion { finally(it) }
+    open fun launch(block: suspend CoroutineScope.() -> Unit): AndroidScope {
+        launch(EmptyCoroutineContext) {
+            block()
+        }.invokeOnCompletion {
+            finally(it)
+        }
         return this
     }
 
-    protected open fun start() {
-
-    }
-
     protected open fun catch(e: Throwable) {
-        catch?.invoke(this, e) ?: handleError(e)
+        launch(adjustDispatcher()) {
+            catch?.invoke(this@AndroidScope, e) ?: handleError(e)
+        }
     }
 
     /**
      * @param e 如果发生异常导致作用域执行完毕, 则该参数为该异常对象, 正常结束则为null
      */
     protected open fun finally(e: Throwable?) {
-        finally?.invoke(this, e)
+        launch(adjustDispatcher()) {
+            finally?.invoke(this@AndroidScope, e)
+        }
     }
 
+    protected fun adjustDispatcher() = if (dispatcher === Dispatchers.Main) dispatcher.immediate else dispatcher
+
+
     /**
      * 当作用域内发生异常时回调
      */
@@ -103,14 +103,12 @@ open class AndroidScope(
 
     open fun cancel(cause: CancellationException? = null) {
         val job = coroutineContext[Job]
-            ?: error("Scope cannot be cancelled because it does not have a job: $this")
+                  ?: error("Scope cannot be cancelled because it does not have a job: $this")
         job.cancel(cause)
     }
 
-    open fun cancel(
-        message: String,
-        cause: Throwable? = null
-    ) = cancel(CancellationException(message, cause))
+    open fun cancel(message: String,
+                    cause: Throwable? = null) = cancel(CancellationException(message, cause))
 
 }
 

+ 5 - 2
net/src/main/java/com/drake/net/scope/DialogCoroutineScope.kt

@@ -23,6 +23,8 @@ import androidx.lifecycle.LifecycleObserver
 import androidx.lifecycle.OnLifecycleEvent
 import com.drake.net.NetConfig
 import com.drake.net.NetConfig.onDialog
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
 
 /**
  * 自动加载对话框网络请求
@@ -40,8 +42,9 @@ import com.drake.net.NetConfig.onDialog
 class DialogCoroutineScope(
     val activity: FragmentActivity,
     var dialog: Dialog? = null,
-    val cancelable: Boolean = true
-) : NetCoroutineScope(), LifecycleObserver {
+    val cancelable: Boolean = true,
+    dispatcher: CoroutineDispatcher = Dispatchers.Main
+                          ) : NetCoroutineScope(dispatcher = dispatcher), LifecycleObserver {
 
     init {
         activity.lifecycle.addObserver(this)

+ 19 - 27
net/src/main/java/com/drake/net/scope/NetCoroutineScope.kt

@@ -17,14 +17,10 @@
 package com.drake.net.scope
 
 import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleEventObserver
 import androidx.lifecycle.LifecycleOwner
 import com.drake.net.NetConfig
 import com.yanzhenjie.kalle.NetCancel
-import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.supervisorScope
+import kotlinx.coroutines.*
 import kotlin.coroutines.EmptyCoroutineContext
 
 
@@ -32,7 +28,9 @@ import kotlin.coroutines.EmptyCoroutineContext
  * 自动显示网络错误信息协程作用域
  */
 @Suppress("unused", "MemberVisibilityCanBePrivate", "NAME_SHADOWING")
-open class NetCoroutineScope() : AndroidScope() {
+open class NetCoroutineScope(lifecycleOwner: LifecycleOwner? = null,
+                             lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
+                             dispatcher: CoroutineDispatcher = Dispatchers.Main) : AndroidScope(lifecycleOwner, lifeEvent, dispatcher) {
 
     protected var isReadCache = true
     protected var preview: (suspend CoroutineScope.() -> Unit)? = null
@@ -45,16 +43,6 @@ open class NetCoroutineScope() : AndroidScope() {
 
     var animate: Boolean = false
 
-    constructor(
-        lifecycleOwner: LifecycleOwner,
-        lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY
-    ) : this() {
-        lifecycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
-            override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
-                if (lifeEvent == event) cancel()
-            }
-        })
-    }
 
     override fun launch(block: suspend CoroutineScope.() -> Unit): NetCoroutineScope {
         launch(EmptyCoroutineContext) {
@@ -77,6 +65,10 @@ open class NetCoroutineScope() : AndroidScope() {
         return this
     }
 
+    protected open fun start() {
+
+    }
+
     override fun finally(e: Throwable?) {
         super.finally(e)
         NetCancel.cancel(uid)
@@ -94,26 +86,26 @@ open class NetCoroutineScope() : AndroidScope() {
     }
 
     override fun catch(e: Throwable) {
-        catch?.invoke(this, e) ?: if (error) handleError(e)
+        launch(adjustDispatcher()) {
+            catch?.invoke(this@NetCoroutineScope, e) ?: if (error) handleError(e)
+        }
     }
 
     /**
-     * "预览"作用域, 该函数一般用于缓存读取
-     * 只在第一次启动作用域时回调
-     * 该函数在作用域[launch]之前执行
+     * "预览"作用域
+     * 该函数一般用于缓存读取, 只在第一次启动作用域时回调
+     * 该函数在作用域[NetCoroutineScope.launch]之前执行
      * 函数内部所有的异常都不会被抛出, 也不会终止作用域执行
      *
-     * @param error 是否在缓存读取成功但网络请求错误时吐司错误信息
+     * @param ignore 是否在缓存读取成功但网络请求错误时吐司错误信息
      * @param animate 是否在缓存成功后依然显示加载动画
      * @param block 该作用域内的所有异常都算缓存读取失败, 不会吐司和打印任何错误
      */
-    fun preview(
-        error: Boolean = false,
-        animate: Boolean = false,
-        block: suspend CoroutineScope.() -> Unit
-    ): AndroidScope {
+    fun preview(ignore: Boolean = false,
+                animate: Boolean = false,
+                block: suspend CoroutineScope.() -> Unit): AndroidScope {
         this.animate = animate
-        this.error = error
+        this.error = ignore
         this.preview = block
         return this
     }

+ 6 - 1
net/src/main/java/com/drake/net/scope/PageCoroutineScope.kt

@@ -20,9 +20,14 @@ import android.view.View
 import com.drake.brv.PageRefreshLayout
 import com.drake.net.NetConfig
 import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
 
 @Suppress("unused", "MemberVisibilityCanBePrivate", "NAME_SHADOWING")
-class PageCoroutineScope(val page: PageRefreshLayout) : NetCoroutineScope() {
+class PageCoroutineScope(
+    val page: PageRefreshLayout,
+    dispatcher: CoroutineDispatcher = Dispatchers.Main
+                        ) : NetCoroutineScope(dispatcher = dispatcher) {
 
     val index get() = page.index
 

+ 6 - 1
net/src/main/java/com/drake/net/scope/StateCoroutineScope.kt

@@ -20,11 +20,16 @@ import android.view.View
 import com.drake.net.NetConfig
 import com.drake.statelayout.StateLayout
 import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
 
 /**
  * 缺省页作用域
  */
-class StateCoroutineScope(val state: StateLayout) : NetCoroutineScope() {
+class StateCoroutineScope(
+    val state: StateLayout,
+    dispatcher: CoroutineDispatcher = Dispatchers.Main
+                         ) : NetCoroutineScope(dispatcher = dispatcher) {
 
     init {
         state.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {

+ 11 - 20
net/src/main/java/com/drake/net/utils/JetPackUtils.kt

@@ -21,7 +21,8 @@ import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentActivity
 import androidx.lifecycle.*
 import com.drake.net.scope.AndroidScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.collect
 import kotlinx.coroutines.flow.distinctUntilChanged
@@ -49,19 +50,15 @@ fun <M> LifecycleOwner.observe(liveData: LiveData<M>?, block: M?.() -> Unit) {
 }
 
 /**
- * 监听数据库
+ * 收集Flow结果并过滤重复结果
  */
-@UseExperimental(ExperimentalCoroutinesApi::class)
-fun <T> Flow<List<T>>.listen(
-    lifecycleOwner: LifecycleOwner? = null,
-    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
-    block: (List<T>) -> Unit
-) {
-    AndroidScope(lifecycleOwner, lifeEvent).launch {
+fun <T> Flow<List<T>>.listen(lifecycleOwner: LifecycleOwner? = null,
+                             lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
+                             dispatcher: CoroutineDispatcher = Dispatchers.Main,
+                             block: (List<T>) -> Unit): AndroidScope {
+    return AndroidScope(lifecycleOwner, lifeEvent, dispatcher).launch {
         distinctUntilChanged().collect { data ->
-            withMain {
-                block(data)
-            }
+            block(data)
         }
     }
 }
@@ -82,18 +79,12 @@ inline fun <reified M : ViewModel> ViewModelStoreOwner.getViewModel(): M {
  * 返回当前组件指定的SavedViewModel
  */
 inline fun <reified M : ViewModel> FragmentActivity.getSavedModel(): M {
-    return ViewModelProvider(
-        this,
-        SavedStateViewModelFactory(application, this)
-    ).get(M::class.java)
+    return ViewModelProvider(this, SavedStateViewModelFactory(application, this)).get(M::class.java)
 }
 
 /**
  * 返回当前组件指定的SavedViewModel
  */
 inline fun <reified M : ViewModel> Fragment.getSavedModel(): M {
-    return ViewModelProvider(
-        this,
-        SavedStateViewModelFactory(activity!!.application, this)
-    ).get(M::class.java)
+    return ViewModelProvider(this, SavedStateViewModelFactory(activity!!.application, this)).get(M::class.java)
 }

+ 43 - 32
net/src/main/java/com/drake/net/utils/ScopeUtils.kt

@@ -49,16 +49,18 @@ import kotlinx.coroutines.sync.withLock
  * 对话框被取消或者界面关闭作用域被取消
  */
 fun FragmentActivity.scopeDialog(
-    dialog: Dialog? = null,
-    cancelable: Boolean = true,
-    block: suspend CoroutineScope.() -> Unit
-) = DialogCoroutineScope(this, dialog, cancelable).launch(block)
+        dialog: Dialog? = null,
+        cancelable: Boolean = true,
+        dispatcher: CoroutineDispatcher = Dispatchers.Main,
+        block: suspend CoroutineScope.() -> Unit
+                                ) = DialogCoroutineScope(this, dialog, cancelable, dispatcher).launch(block)
 
 fun Fragment.scopeDialog(
-    dialog: Dialog? = null,
-    cancelable: Boolean = true,
-    block: suspend CoroutineScope.() -> Unit
-) = DialogCoroutineScope(requireActivity(), dialog, cancelable).launch(block)
+        dialog: Dialog? = null,
+        cancelable: Boolean = true,
+        dispatcher: CoroutineDispatcher = Dispatchers.Main,
+        block: suspend CoroutineScope.() -> Unit
+                        ) = DialogCoroutineScope(requireActivity(), dialog, cancelable, dispatcher).launch(block)
 
 // </editor-fold>
 
@@ -74,8 +76,9 @@ fun Fragment.scopeDialog(
  *
  * 布局被销毁或者界面关闭作用域被取消
  */
-fun StateLayout.scope(block: suspend CoroutineScope.() -> Unit): NetCoroutineScope {
-    val scope = StateCoroutineScope(this)
+fun StateLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main,
+                      block: suspend CoroutineScope.() -> Unit): NetCoroutineScope {
+    val scope = StateCoroutineScope(this, dispatcher)
     scope.launch(block)
     return scope
 }
@@ -93,8 +96,9 @@ fun StateLayout.scope(block: suspend CoroutineScope.() -> Unit): NetCoroutineSco
  *
  * 布局被销毁或者界面关闭作用域被取消
  */
-fun PageRefreshLayout.scope(block: suspend CoroutineScope.() -> Unit): PageCoroutineScope {
-    val scope = PageCoroutineScope(this)
+fun PageRefreshLayout.scope(dispatcher: CoroutineDispatcher = Dispatchers.Main,
+                            block: suspend CoroutineScope.() -> Unit): PageCoroutineScope {
+    val scope = PageCoroutineScope(this, dispatcher)
     scope.launch(block)
     return scope
 }
@@ -104,19 +108,22 @@ fun PageRefreshLayout.scope(block: suspend CoroutineScope.() -> Unit): PageCorou
  *
  * 该作用域生命周期跟随整个应用, 注意内存泄漏
  */
-fun scope(block: suspend CoroutineScope.() -> Unit): AndroidScope {
-    return AndroidScope().launch(block)
+fun scope(dispatcher: CoroutineDispatcher = Dispatchers.Main,
+          block: suspend CoroutineScope.() -> Unit): AndroidScope {
+    return AndroidScope(dispatcher = dispatcher).launch(block)
 }
 
 fun LifecycleOwner.scopeLife(
-    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
-    block: suspend CoroutineScope.() -> Unit
-) = AndroidScope(this, lifeEvent).launch(block)
+        lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
+        dispatcher: CoroutineDispatcher = Dispatchers.Main,
+        block: suspend CoroutineScope.() -> Unit
+                            ) = AndroidScope(this, lifeEvent, dispatcher).launch(block)
 
 fun Fragment.scopeLife(
-    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_STOP,
-    block: suspend CoroutineScope.() -> Unit
-) = AndroidScope(this, lifeEvent).launch(block)
+        lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_STOP,
+        dispatcher: CoroutineDispatcher = Dispatchers.Main,
+        block: suspend CoroutineScope.() -> Unit
+                      ) = AndroidScope(this, lifeEvent, dispatcher).launch(block)
 
 /**
  * 网络请求的异步作用域
@@ -124,29 +131,33 @@ fun Fragment.scopeLife(
  *
  * 该作用域生命周期跟随整个应用, 注意内存泄漏
  */
-fun scopeNet(block: suspend CoroutineScope.() -> Unit) = NetCoroutineScope().launch(block)
+fun scopeNet(dispatcher: CoroutineDispatcher = Dispatchers.Main,
+             block: suspend CoroutineScope.() -> Unit) = NetCoroutineScope(dispatcher = dispatcher).launch(block)
 
 
 fun LifecycleOwner.scopeNetLife(
-    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
-    block: suspend CoroutineScope.() -> Unit
-) = NetCoroutineScope(this, lifeEvent).launch(block)
+        lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
+        dispatcher: CoroutineDispatcher = Dispatchers.Main,
+        block: suspend CoroutineScope.() -> Unit
+                               ) = NetCoroutineScope(this, lifeEvent, dispatcher).launch(block)
 
 /**
  * Fragment应当在[Lifecycle.Event.ON_STOP]时就取消作用域, 避免[Fragment.onDestroyView]导致引用空视图
  */
 fun Fragment.scopeNetLife(
-    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_STOP,
-    block: suspend CoroutineScope.() -> Unit
-) = NetCoroutineScope(this, lifeEvent).launch(block)
+        lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_STOP,
+        dispatcher: CoroutineDispatcher = Dispatchers.Main,
+        block: suspend CoroutineScope.() -> Unit
+                         ) = NetCoroutineScope(this, lifeEvent, dispatcher).launch(block)
 
 
-@UseExperimental(InternalCoroutinesApi::class)
+@OptIn(InternalCoroutinesApi::class)
 inline fun <T> Flow<T>.scope(
-    owner: LifecycleOwner? = null,
-    event: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
-    crossinline action: suspend (value: T) -> Unit
-): CoroutineScope = AndroidScope(owner, event).launch {
+        owner: LifecycleOwner? = null,
+        event: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
+        dispatcher: CoroutineDispatcher = Dispatchers.Main,
+        crossinline action: suspend (value: T) -> Unit
+                            ): AndroidScope = AndroidScope(owner, event, dispatcher).launch {
     this@scope.collect(object : FlowCollector<T> {
         override suspend fun emit(value: T) = action(value)
     })

+ 14 - 4
sample/src/main/java/com/drake/net/sample/ui/fragment/RequestMethodFragment.kt

@@ -23,21 +23,31 @@ import android.view.*
 import androidx.fragment.app.Fragment
 import com.drake.net.*
 import com.drake.net.sample.R
+import com.drake.net.utils.scopeNet
 import com.drake.net.utils.scopeNetLife
 import kotlinx.android.synthetic.main.fragment_async_task.*
 
 
 class RequestMethodFragment : Fragment() {
 
-    override fun onCreateView(
-            inflater: LayoutInflater, container: ViewGroup?,
-            savedInstanceState: Bundle?
-                             ): View? {
+    override fun onCreateView(inflater: LayoutInflater,
+                              container: ViewGroup?,
+                              savedInstanceState: Bundle?): View? {
         setHasOptionsMenu(true)
         return inflater.inflate(R.layout.fragment_request_method, container, false)
     }
 
 
+    override fun onActivityCreated(savedInstanceState: Bundle?) {
+        super.onActivityCreated(savedInstanceState)
+
+        scopeNet {
+            throw NullPointerException()
+        }.catch {
+            handleError(it)
+        }
+    }
+
     private fun GET() {
         scopeNetLife {
             tv_fragment.text = Get<String>("api").await()