Browse Source

Fastest现在可在作用域内部捕获异常, 更新文档

drake 4 years ago
parent
commit
5fbfa9e112

+ 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.9'
+implementation 'com.github.liangjingkanji:BRV:1.3.12'
 
-implementation 'com.github.liangjingkanji:Net:2.2.18'
+implementation 'com.github.liangjingkanji:Net:2.2.19'
 ```
 
 <br>

+ 1 - 1
build.gradle

@@ -19,7 +19,7 @@
 buildscript {
     ext {
         kotlin_version = '1.4.10'
-        brv_version = '1.3.11'
+        brv_version = '1.3.12'
         coroutine_version = '1.3.7'
         glide_version = '4.9.0'
         room_version = "2.2.5"

+ 18 - 0
docs/fastest.md

@@ -42,6 +42,24 @@ scopeNetLife {
 
 有的场景下并发的接口返回的数据类型不同, 但是fastest只能返回一个类型, 我们可以使`transform`的回调函数返回结果都拥有一个共同的接口, 然后去类型判断
 
+## 捕获Fastest
+```kotlin
+scopeNetLife {
+    val task = Get<String>("api2")
+    val task1 = Get<String>("api2")
+    val task2 = Get<String>("api2")
+
+    val data = try {
+        fastest(task, task1, task2) // 当 task/task1/task2 全部异常之后再并发执行 backupTask/backupTask1
+    } catch (e: Exception) {
+        val backupTask = Get<String>("api2")
+        val backupTask1 = Get<String>("api")
+        fastest(backupTask, backupTask1)
+    }
+}
+```
+
+
 <br>
 
 !!! note

+ 101 - 0
docs/tag.md

@@ -0,0 +1,101 @@
+Net支持的`标签`功能, 其标签能够贯穿网络请求的生命周期
+<br>
+在拦截器(Interceptor)或者转换器(Convert)中都可以通过`request.tag()`获取到标签
+
+
+## 标签使用
+
+### 1) 设置标签
+```kotlin hl_lines="2"
+scopeNetLife {
+    tv_fragment.text = Get<String>("api", tag = RESPONSE).await()
+}
+```
+
+### 2) 拦截器中获取标签
+```kotlin hl_lines="4"
+class NetInterceptor : Interceptor {
+    override fun intercept(chain: Chain): Response {
+
+        val request = chain.request()
+
+        if (request.tag() == RESPONSE) {
+            // 可以打印响应体或者其他逻辑
+        }
+        return chain.proceed(request)
+    }
+}
+```
+
+### 3) 转换器中获取标签
+
+```kotlin hl_lines="10"
+class JsonConvert : DefaultConvert(code = "code", message = "msg", success = "200") {
+
+    override fun <S, F> convert(succeed: Type,
+                                failed: Type,
+                                request: Request,
+                                response: Response,
+                                result: Result<S, F>) {
+        super.convert(succeed, failed, request, response, result)
+
+        if (request.tag() == RESPONSE) { // 判断标签
+            // 执行你的逻辑
+        }
+    }
+
+    override fun <S> String.parseBody(succeed: Type): S? {
+        return Moshi.Builder().build().adapter<S>(succeed).fromJson(this)
+    }
+}
+```
+
+
+
+## 多标签
+创建一个类继承TAG, 即可通过加减符号来添加多标签
+
+上面例子使用的`RESPONSE`就是一个示例
+```kotlin
+/**
+ * 响应体打印标签
+ */
+object RESPONSE : TAG()
+
+/**
+ * 请求参数打印标签
+ */
+object REQUEST : TAG()
+```
+
+1) 设置标签
+
+```kotlin
+scopeNetLife {
+    tv_fragment.text = Get<String>("api", tag = RESPONSE + REQUEST).await()
+}
+```
+
+2) 判断包含标签
+
+```kotlin hl_lines="7 10"
+class NetInterceptor : Interceptor {
+    override fun intercept(chain: Chain): Response {
+        val request = chain.request()
+
+        val tag = request.tag() as TAG
+
+        if (tag.contains(REQUEST)) {
+            // 可以打印响应体或者其他逻辑
+        }
+        if (tag.contains(RESPONSE)) {
+            // 可以打印请求体或者其他逻辑
+        }
+        return chain.proceed(request)
+    }
+}
+```
+<br>
+
+!!! note
+    RESPONSE 和 REQUEST 已经在Net框架中存在, 可以直接使用

+ 1 - 0
mkdocs.yml

@@ -48,6 +48,7 @@ nav:
       - 自动分页加载: auto-page.md
       - 自动错误处理: auto-error-handle.md
   - 切换调度器: switch-dispatcher.md
+  - 标签: tag.md
   - 上传文件: upload-file.md
   - 下载文件: download-file.md
   - 下载图片: download-image.md

+ 4 - 1
net/src/main/java/com/drake/net/transform/DeferredTransform.kt

@@ -18,7 +18,10 @@ package com.drake.net.transform
 
 import kotlinx.coroutines.Deferred
 
-
+/**
+ * 可以将[Deferred]返回结果进行转换
+ * [block]在[Deferred]执行成功返回结果时执行
+ */
 fun <T, R> Deferred<T>.transform(block: (T) -> R): DeferredTransform<T, R> {
     return DeferredTransform(this, block)
 }

+ 18 - 19
net/src/main/java/com/drake/net/utils/Fastest.kt

@@ -19,7 +19,6 @@ package com.drake.net.utils
 import com.drake.net.transform.DeferredTransform
 import com.yanzhenjie.kalle.NetCancel
 import kotlinx.coroutines.*
-import kotlinx.coroutines.channels.Channel
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 
@@ -33,7 +32,7 @@ import kotlinx.coroutines.sync.withLock
 @OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("SuspendFunctionOnCoroutineScope")
 suspend fun <T> CoroutineScope.fastest(vararg deferredArray: Deferred<T>): T {
-    val chan = Channel<T>()
+    val deferred = CompletableDeferred<T>()
     val mutex = Mutex()
     deferredArray.forEach {
         launch(Dispatchers.IO) {
@@ -41,18 +40,18 @@ suspend fun <T> CoroutineScope.fastest(vararg deferredArray: Deferred<T>): T {
                 val result = it.await()
                 mutex.withLock {
                     NetCancel.cancel(coroutineContext[CoroutineExceptionHandler])
-                    chan.send(result)
+                    deferred.complete(result)
                 }
             } catch (e: Exception) {
                 it.cancel()
                 val allFail = deferredArray.all { it.isCancelled }
-                if (allFail) throw e else {
+                if (allFail) deferred.completeExceptionally(e) else {
                     if (e !is CancellationException) e.printStackTrace()
                 }
             }
         }
     }
-    return chan.receive()
+    return deferred.await()
 }
 
 /**
@@ -64,7 +63,7 @@ suspend fun <T> CoroutineScope.fastest(vararg deferredArray: Deferred<T>): T {
 @OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("SuspendFunctionOnCoroutineScope")
 suspend fun <T> CoroutineScope.fastest(deferredArray: List<Deferred<T>>): T {
-    val chan = Channel<T>()
+    val deferred = CompletableDeferred<T>()
     val mutex = Mutex()
     deferredArray.forEach {
         launch(Dispatchers.IO) {
@@ -72,18 +71,18 @@ suspend fun <T> CoroutineScope.fastest(deferredArray: List<Deferred<T>>): T {
                 val result = it.await()
                 mutex.withLock {
                     NetCancel.cancel(coroutineContext[CoroutineExceptionHandler])
-                    chan.send(result)
+                    deferred.complete(result)
                 }
             } catch (e: Exception) {
                 it.cancel()
                 val allFail = deferredArray.all { it.isCancelled }
-                if (allFail) throw e else {
+                if (allFail) deferred.completeExceptionally(e) else {
                     if (e !is CancellationException) e.printStackTrace()
                 }
             }
         }
     }
-    return chan.receive()
+    return deferred.await()
 }
 
 /**
@@ -96,7 +95,7 @@ suspend fun <T> CoroutineScope.fastest(deferredArray: List<Deferred<T>>): T {
 @OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("SuspendFunctionOnCoroutineScope")
 suspend fun <T, R> CoroutineScope.fastest(vararg deferredArray: DeferredTransform<T, R>): R {
-    val chan = Channel<R>()
+    val deferred = CompletableDeferred<R>()
     val mutex = Mutex()
     deferredArray.forEach {
         launch(Dispatchers.IO) {
@@ -104,21 +103,21 @@ suspend fun <T, R> CoroutineScope.fastest(vararg deferredArray: DeferredTransfor
                 val result = it.deferred.await()
                 mutex.withLock {
                     NetCancel.cancel(coroutineContext[CoroutineExceptionHandler])
-                    if (!chan.isClosedForSend) {
+                    if (!deferred.isCompleted) {
                         val transformResult = it.block(result)
-                        chan.send(transformResult)
+                        deferred.complete(transformResult)
                     }
                 }
             } catch (e: Exception) {
                 it.deferred.cancel()
                 val allFail = deferredArray.all { it.deferred.isCancelled }
-                if (allFail) throw e else {
+                if (allFail) deferred.completeExceptionally(e) else {
                     if (e !is CancellationException) e.printStackTrace()
                 }
             }
         }
     }
-    return chan.receive()
+    return deferred.await()
 }
 
 /**
@@ -132,7 +131,7 @@ suspend fun <T, R> CoroutineScope.fastest(vararg deferredArray: DeferredTransfor
 @OptIn(ExperimentalCoroutinesApi::class)
 @Suppress("SuspendFunctionOnCoroutineScope")
 suspend fun <T, R> CoroutineScope.fastest(deferredList: List<DeferredTransform<T, R>>): R {
-    val chan = Channel<R>()
+    val deferred = CompletableDeferred<R>()
     val mutex = Mutex()
     deferredList.forEach {
         launch(Dispatchers.IO) {
@@ -140,19 +139,19 @@ suspend fun <T, R> CoroutineScope.fastest(deferredList: List<DeferredTransform<T
                 val result = it.deferred.await()
                 mutex.withLock {
                     NetCancel.cancel(coroutineContext[CoroutineExceptionHandler])
-                    if (!chan.isClosedForSend) {
+                    if (!deferred.isCompleted) {
                         val transformResult = it.block(result)
-                        chan.send(transformResult)
+                        deferred.complete(transformResult)
                     }
                 }
             } catch (e: Exception) {
                 it.deferred.cancel()
                 val allFail = deferredList.all { it.deferred.isCancelled }
-                if (allFail) throw e else {
+                if (allFail) deferred.completeExceptionally(e) else {
                     if (e !is CancellationException) e.printStackTrace()
                 }
             }
         }
     }
-    return chan.receive()
+    return deferred.await()
 }

+ 40 - 0
sample/src/main/java/com/drake/net/sample/callback/NetInterceptor.kt

@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 Drake, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.drake.net.sample.callback
+
+import com.drake.net.tag.REQUEST
+import com.drake.net.tag.RESPONSE
+import com.drake.net.tag.TAG
+import com.yanzhenjie.kalle.Response
+import com.yanzhenjie.kalle.connect.Interceptor
+import com.yanzhenjie.kalle.connect.http.Chain
+
+class NetInterceptor : Interceptor {
+    override fun intercept(chain: Chain): Response {
+        val request = chain.request()
+
+        val tag = request.tag() as TAG
+
+        if (tag.contains(REQUEST)) {
+            // 可以打印响应体或者其他逻辑
+        }
+        if (tag.contains(RESPONSE)) {
+            // 可以打印请求体或者其他逻辑
+        }
+        return chain.proceed(request)
+    }
+}

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/InterceptorFragment.kt

@@ -42,7 +42,7 @@ class InterceptorFragment : Fragment() {
 
         scopeNetLife {
             tv_fragment.text = Get<String>("api") {
-                // 拦截器只支持全局, 无法单例
+                // 拦截器只支持全局, 无法单例, 请查看[com.drake.net.sample.callback.NetInterceptor]
             }.await()
         }
     }