Browse Source

| 优化取消网络请求

drake 4 years ago
parent
commit
a2aee1d64e

+ 1 - 1
README.md

@@ -89,7 +89,7 @@ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
 // 支持自动下拉刷新和缺省页的, 可选, 刷新头和上拉加载参考SmartRefreshLayout (可选)
 implementation 'com.github.liangjingkanji:BRV:1.3.6'
 
-implementation 'com.github.liangjingkanji:Net:2.2.4'
+implementation 'com.github.liangjingkanji:Net:2.2.5'
 ```
 
 

+ 5 - 8
kalle/src/main/java/com/yanzhenjie/kalle/Canceller.java → kalle/src/main/java/com/yanzhenjie/kalle/Canceller.kt

@@ -13,19 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.yanzhenjie.kalle;
+package com.yanzhenjie.kalle
 
-/**
- * Created by Zhenjie Yan on 2018/2/27.
- */
-public interface Canceller {
+interface Canceller {
     /**
      * Cancel operation.
      */
-    void cancel();
+    fun cancel()
 
     /**
      * Operation is canceled.
      */
-    boolean isCancelled();
-}
+    val isCancelled: Boolean
+}

+ 12 - 9
kalle/src/main/java/com/yanzhenjie/kalle/Canceler.kt → kalle/src/main/java/com/yanzhenjie/kalle/NetDispose.kt

@@ -16,9 +16,9 @@
 package com.yanzhenjie.kalle
 
 
-object Canceler {
+object NetDispose {
 
-    private val map = mutableMapOf<Any, Canceller>()
+    private val map = mutableMapOf<Canceller, Any>()
 
     /**
      * Add a task to cancel.
@@ -26,9 +26,9 @@ object Canceler {
      * @param uid   target request.
      * @param canceller canceller.
      */
-    fun addCancel(uid: Any?, canceller: Canceller) {
+    fun add(uid: Any?, canceller: Canceller) {
         uid ?: return
-        map[uid] = canceller
+        map[canceller] = uid
     }
 
     /**
@@ -36,23 +36,26 @@ object Canceler {
      *
      * @param uid target request.
      */
-    fun removeCancel(uid: Any?) {
+    fun remove(uid: Any?) {
         uid ?: return
-        map.remove(uid)
+        val iterator = map.iterator()
+        while (iterator.hasNext()) {
+            if (iterator.next().value == uid) iterator.remove()
+        }
     }
 
     /**
      * According to the tag to cancel a task.
      *
      */
-    fun cancel(uid: Any?) {
+    fun dispose(uid: Any?) {
         uid ?: return
         val iterator = map.iterator()
         while (iterator.hasNext()) {
             val next = iterator.next()
-            if (uid == next.key) {
+            if (uid == next.value) {
                 iterator.remove()
-                next.value.cancel()
+                next.key.cancel()
             }
         }
     }

+ 7 - 7
kalle/src/main/java/com/yanzhenjie/kalle/download/DownloadManager.java

@@ -15,9 +15,9 @@
  */
 package com.yanzhenjie.kalle.download;
 
-import com.yanzhenjie.kalle.Canceler;
 import com.yanzhenjie.kalle.Canceller;
 import com.yanzhenjie.kalle.Kalle;
+import com.yanzhenjie.kalle.NetDispose;
 
 import java.util.concurrent.Executor;
 
@@ -56,10 +56,10 @@ public class DownloadManager {
             @Override
             public void onEnd() {
                 super.onEnd();
-                Canceler.INSTANCE.removeCancel(download.uid());
+                NetDispose.INSTANCE.remove(download.uid());
             }
         });
-        Canceler.INSTANCE.addCancel(download.uid(), work);
+        NetDispose.INSTANCE.add(download.uid(), work);
         mExecutor.execute(work);
         return work;
     }
@@ -72,7 +72,7 @@ public class DownloadManager {
      */
     public String perform(UrlDownload download) throws Exception {
         UrlWorker worker = new UrlWorker(download);
-        Canceler.INSTANCE.addCancel(download.uid(), worker);
+        NetDispose.INSTANCE.add(download.uid(), worker);
         return worker.call();
     }
 
@@ -88,10 +88,10 @@ public class DownloadManager {
             @Override
             public void onEnd() {
                 super.onEnd();
-                Canceler.INSTANCE.removeCancel(download.uid());
+                NetDispose.INSTANCE.remove(download.uid());
             }
         });
-        Canceler.INSTANCE.addCancel(download.uid(), work);
+        NetDispose.INSTANCE.add(download.uid(), work);
         mExecutor.execute(work);
         return work;
     }
@@ -104,7 +104,7 @@ public class DownloadManager {
      */
     public String perform(BodyDownload download) throws Exception {
         BodyWorker worker = new BodyWorker(download);
-        Canceler.INSTANCE.addCancel(download.uid(), worker);
+        NetDispose.INSTANCE.add(download.uid(), worker);
         return worker.call();
     }
 

+ 7 - 7
kalle/src/main/java/com/yanzhenjie/kalle/simple/RequestManager.java

@@ -15,9 +15,9 @@
  */
 package com.yanzhenjie.kalle.simple;
 
-import com.yanzhenjie.kalle.Canceler;
 import com.yanzhenjie.kalle.Canceller;
 import com.yanzhenjie.kalle.Kalle;
+import com.yanzhenjie.kalle.NetDispose;
 
 import java.lang.reflect.Type;
 import java.util.concurrent.Executor;
@@ -59,10 +59,10 @@ public class RequestManager {
             @Override
             public void onEnd() {
                 super.onEnd();
-                Canceler.INSTANCE.removeCancel(request.uid());
+                NetDispose.INSTANCE.remove(request.uid());
             }
         });
-        Canceler.INSTANCE.addCancel(request.uid(), work);
+        NetDispose.INSTANCE.add(request.uid(), work);
         mExecutor.execute(work);
         return work;
     }
@@ -79,7 +79,7 @@ public class RequestManager {
      */
     public <S, F> Result<S, F> perform(SimpleUrlRequest request, Type succeed, Type failed) throws Exception {
         UrlWorker<S, F> worker = new UrlWorker<>(request, succeed, failed);
-        Canceler.INSTANCE.addCancel(request.uid(), worker);
+        NetDispose.INSTANCE.add(request.uid(), worker);
         return worker.call();
     }
 
@@ -97,10 +97,10 @@ public class RequestManager {
             @Override
             public void onEnd() {
                 super.onEnd();
-                Canceler.INSTANCE.removeCancel(request.uid());
+                NetDispose.INSTANCE.remove(request.uid());
             }
         });
-        Canceler.INSTANCE.addCancel(request.uid(), work);
+        NetDispose.INSTANCE.add(request.uid(), work);
         mExecutor.execute(work);
         return work;
     }
@@ -117,7 +117,7 @@ public class RequestManager {
      */
     public <S, F> Result<S, F> perform(SimpleBodyRequest request, Type succeed, Type failed) throws Exception {
         BodyWorker<S, F> worker = new BodyWorker<>(request, succeed, failed);
-        Canceler.INSTANCE.addCancel(request.uid(), worker);
+        NetDispose.INSTANCE.add(request.uid(), worker);
         return worker.call();
     }
 

+ 179 - 186
net/src/main/java/com/drake/net/Net.kt

@@ -12,7 +12,7 @@ package com.drake.net
 import android.content.Context
 import com.bumptech.glide.Glide
 import com.drake.net.error.ResponseException
-import com.yanzhenjie.kalle.Canceler
+import com.yanzhenjie.kalle.NetDispose
 import com.yanzhenjie.kalle.RequestMethod
 import com.yanzhenjie.kalle.Url
 import com.yanzhenjie.kalle.download.BodyDownload
@@ -36,17 +36,16 @@ import java.net.SocketException
  * @return Observable<M> 结果会在主线程
  */
 
-inline fun <reified M> CoroutineScope.Get(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
+inline fun <reified M> CoroutineScope.Get(path: String,
+                                          tag: Any? = null,
+                                          cache: CacheMode = CacheMode.HTTP,
+                                          absolutePath: Boolean = false,
+                                          uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                          noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
     if (!isActive) throw CancellationException()
 
-    val uid = coroutineContext[CoroutineExceptionHandler]
     coroutineContext[Job]?.invokeOnCompletion {
-        if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+        if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
     }
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -67,18 +66,17 @@ inline fun <reified M> CoroutineScope.Get(
 }
 
 
-inline fun <reified M> CoroutineScope.Post(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}): Deferred<M> =
+inline fun <reified M> CoroutineScope.Post(path: String,
+                                           tag: Any? = null,
+                                           cache: CacheMode = CacheMode.HTTP,
+                                           absolutePath: Boolean = false,
+                                           uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                           noinline block: SimpleBodyRequest.Api.() -> Unit = {}): Deferred<M> =
         async(Dispatchers.IO) {
             if (!isActive) throw CancellationException()
 
-            val uid = coroutineContext[CoroutineExceptionHandler]
             coroutineContext[Job]?.invokeOnCompletion {
-                if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+                if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
             }
 
             val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -99,17 +97,16 @@ inline fun <reified M> CoroutineScope.Post(
             if (response.isSucceed) response.success!! else throw response.failure!!
         }
 
-inline fun <reified M> CoroutineScope.Head(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
+inline fun <reified M> CoroutineScope.Head(path: String,
+                                           tag: Any? = null,
+                                           cache: CacheMode = CacheMode.HTTP,
+                                           absolutePath: Boolean = false,
+                                           uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                           noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
     if (!isActive) throw CancellationException()
 
-    val uid = coroutineContext[CoroutineExceptionHandler]
     coroutineContext[Job]?.invokeOnCompletion {
-        if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+        if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
     }
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -130,17 +127,16 @@ inline fun <reified M> CoroutineScope.Head(
     if (response.isSucceed) response.success!! else throw response.failure!!
 }
 
-inline fun <reified M> CoroutineScope.Options(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
+inline fun <reified M> CoroutineScope.Options(path: String,
+                                              tag: Any? = null,
+                                              cache: CacheMode = CacheMode.HTTP,
+                                              absolutePath: Boolean = false,
+                                              uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                              noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
     if (!isActive) throw CancellationException()
 
-    val uid = coroutineContext[CoroutineExceptionHandler]
     coroutineContext[Job]?.invokeOnCompletion {
-        if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+        if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
     }
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -162,17 +158,16 @@ inline fun <reified M> CoroutineScope.Options(
 }
 
 
-inline fun <reified M> CoroutineScope.Trace(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
+inline fun <reified M> CoroutineScope.Trace(path: String,
+                                            tag: Any? = null,
+                                            cache: CacheMode = CacheMode.HTTP,
+                                            absolutePath: Boolean = false,
+                                            uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                            noinline block: SimpleUrlRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
     if (!isActive) throw CancellationException()
 
-    val uid = coroutineContext[CoroutineExceptionHandler]
     coroutineContext[Job]?.invokeOnCompletion {
-        if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+        if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
     }
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -193,18 +188,16 @@ inline fun <reified M> CoroutineScope.Trace(
     if (response.isSucceed) response.success!! else throw response.failure!!
 }
 
-inline fun <reified M> CoroutineScope.Delete(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}
-                                            ): Deferred<M> = async(Dispatchers.IO) {
+inline fun <reified M> CoroutineScope.Delete(path: String,
+                                             tag: Any? = null,
+                                             cache: CacheMode = CacheMode.HTTP,
+                                             absolutePath: Boolean = false,
+                                             uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                             noinline block: SimpleBodyRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
     if (!isActive) throw CancellationException()
 
-    val uid = coroutineContext[CoroutineExceptionHandler]
     coroutineContext[Job]?.invokeOnCompletion {
-        if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+        if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
     }
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -225,71 +218,65 @@ inline fun <reified M> CoroutineScope.Delete(
     if (response.isSucceed) response.success!! else throw response.failure!!
 }
 
-inline fun <reified M> CoroutineScope.Put(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}): Deferred<M> =
-        async(Dispatchers.IO) {
-            if (!isActive) throw CancellationException()
+inline fun <reified M> CoroutineScope.Put(path: String,
+                                          tag: Any? = null,
+                                          cache: CacheMode = CacheMode.HTTP,
+                                          absolutePath: Boolean = false,
+                                          uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                          noinline block: SimpleBodyRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
+    if (!isActive) throw CancellationException()
 
-            val uid = coroutineContext[CoroutineExceptionHandler]
-            coroutineContext[Job]?.invokeOnCompletion {
-                if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
-            }
+    coroutineContext[Job]?.invokeOnCompletion {
+        if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
+    }
 
-            val realPath = if (absolutePath) path else (NetConfig.host + path)
+    val realPath = if (absolutePath) path else (NetConfig.host + path)
 
-            val request = SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(),
-                                                   RequestMethod.PUT)
-                    .tag(tag)
-                    .uid(uid)
-                    .cacheKey(path)
-                    .cacheMode(cache)
+    val request = SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(),
+                                           RequestMethod.PUT)
+            .tag(tag)
+            .uid(uid)
+            .cacheKey(path)
+            .cacheMode(cache)
 
-            val response = try {
-                request.apply(block)
-                        .perform<M, ResponseException>(M::class.java, ResponseException::class.java)
-            } catch (e: SocketException) {
-                throw CancellationException()
-            }
+    val response = try {
+        request.apply(block)
+                .perform<M, ResponseException>(M::class.java, ResponseException::class.java)
+    } catch (e: SocketException) {
+        throw CancellationException()
+    }
 
-            if (response.isSucceed) response.success!! else throw response.failure!!
-        }
+    if (response.isSucceed) response.success!! else throw response.failure!!
+}
 
-inline fun <reified M> CoroutineScope.Patch(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}): Deferred<M> =
-        async(Dispatchers.IO) {
-            if (!isActive) throw CancellationException()
+inline fun <reified M> CoroutineScope.Patch(path: String,
+                                            tag: Any? = null,
+                                            cache: CacheMode = CacheMode.HTTP,
+                                            absolutePath: Boolean = false,
+                                            uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                            noinline block: SimpleBodyRequest.Api.() -> Unit = {}): Deferred<M> = async(Dispatchers.IO) {
+    if (!isActive) throw CancellationException()
 
-            val uid = coroutineContext[CoroutineExceptionHandler]
-            coroutineContext[Job]?.invokeOnCompletion {
-                if (it != null) Canceler.cancel(uid) else Canceler.removeCancel(uid)
-            }
+    coroutineContext[Job]?.invokeOnCompletion {
+        if (it != null) NetDispose.dispose(uid) else NetDispose.remove(uid)
+    }
 
-            val realPath = if (absolutePath) path else (NetConfig.host + path)
+    val realPath = if (absolutePath) path else (NetConfig.host + path)
 
-            val request =
-                    SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.PATCH)
-                            .tag(tag)
-                            .uid(uid)
-                            .cacheKey(path)
-                            .cacheMode(cache)
+    val request = SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.PATCH)
+            .tag(tag)
+            .uid(uid)
+            .cacheKey(path)
+            .cacheMode(cache)
 
-            val response = try {
-                request.apply(block)
-                        .perform<M, ResponseException>(M::class.java, ResponseException::class.java)
-            } catch (e: SocketException) {
-                throw CancellationException()
-            }
+    val response = try {
+        request.apply(block).perform<M, ResponseException>(M::class.java, ResponseException::class.java)
+    } catch (e: SocketException) {
+        throw CancellationException()
+    }
 
-            if (response.isSucceed) response.success!! else throw response.failure!!
-        }
+    if (response.isSucceed) response.success!! else throw response.failure!!
+}
 
 /**
  * 用于提交URL体下载文件(默认GET请求)
@@ -301,13 +288,13 @@ inline fun <reified M> CoroutineScope.Patch(
  * @param absolutePath  下载链接是否是绝对路径
  * @param block 请求参数
  */
-fun CoroutineScope.Download(
-        path: String,
-        dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
-        tag: Any? = null,
-        absolutePath: Boolean = false,
-        method: RequestMethod = RequestMethod.GET,
-        block: UrlDownload.Api.() -> Unit = {}): Deferred<String> = async(Dispatchers.IO) {
+fun CoroutineScope.Download(path: String,
+                            dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
+                            tag: Any? = null,
+                            absolutePath: Boolean = false,
+                            method: RequestMethod = RequestMethod.GET,
+                            uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                            block: UrlDownload.Api.() -> Unit = {}): Deferred<String> = async(Dispatchers.IO) {
 
     if (!isActive) throw CancellationException()
 
@@ -315,9 +302,8 @@ fun CoroutineScope.Download(
         throw UnsupportedOperationException("You should use [DownloadBody] function")
     }
 
-    val uid = coroutineContext[CoroutineExceptionHandler]
     coroutineContext[Job]?.invokeOnCompletion {
-        if (it != null && it !is CancellationException) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+        if (it != null && it !is CancellationException) NetDispose.dispose(uid) else NetDispose.remove(uid)
     }
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -334,13 +320,13 @@ fun CoroutineScope.Download(
 /**
  * 用于提交请求体下载文件(默认POST请求)
  */
-fun CoroutineScope.DownloadBody(
-        path: String,
-        dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
-        tag: Any? = null,
-        absolutePath: Boolean = false,
-        method: RequestMethod = RequestMethod.POST,
-        block: BodyDownload.Api.() -> Unit = {}): Deferred<String> = async(Dispatchers.IO) {
+fun CoroutineScope.DownloadBody(path: String,
+                                dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
+                                tag: Any? = null,
+                                absolutePath: Boolean = false,
+                                method: RequestMethod = RequestMethod.POST,
+                                uid: CoroutineExceptionHandler? = coroutineContext[CoroutineExceptionHandler],
+                                block: BodyDownload.Api.() -> Unit = {}): Deferred<String> = async(Dispatchers.IO) {
 
     if (!isActive) throw CancellationException()
 
@@ -348,9 +334,8 @@ fun CoroutineScope.DownloadBody(
         throw UnsupportedOperationException("You should use [Download] function")
     }
 
-    val uid = coroutineContext[CoroutineExceptionHandler]
     coroutineContext[Job]?.invokeOnCompletion {
-        if (it != null && it !is CancellationException) Canceler.cancel(uid) else Canceler.removeCancel(uid)
+        if (it != null && it !is CancellationException) NetDispose.dispose(uid) else NetDispose.remove(uid)
     }
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
@@ -392,17 +377,18 @@ fun CoroutineScope.DownloadImage(url: String, with: Int = -1, height: Int = -1):
 
 // <editor-fold desc="同步请求">
 
-inline fun <reified M> syncGet(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncGet(path: String,
+                               tag: Any? = null,
+                               cache: CacheMode = CacheMode.HTTP,
+                               absolutePath: Boolean = false,
+                               uid: Any? = null,
+                               noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleUrlRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.GET)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -416,17 +402,18 @@ inline fun <reified M> syncGet(
     }
 }
 
-inline fun <reified M> syncPost(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncPost(path: String,
+                                tag: Any? = null,
+                                cache: CacheMode = CacheMode.HTTP,
+                                absolutePath: Boolean = false,
+                                uid: Any? = null,
+                                noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.POST)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -440,17 +427,18 @@ inline fun <reified M> syncPost(
     }
 }
 
-inline fun <reified M> syncHead(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncHead(path: String,
+                                tag: Any? = null,
+                                cache: CacheMode = CacheMode.HTTP,
+                                absolutePath: Boolean = false,
+                                uid: Any? = null,
+                                noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleUrlRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.HEAD)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -464,17 +452,18 @@ inline fun <reified M> syncHead(
     }
 }
 
-inline fun <reified M> syncOptions(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncOptions(path: String,
+                                   tag: Any? = null,
+                                   cache: CacheMode = CacheMode.HTTP,
+                                   absolutePath: Boolean = false,
+                                   uid: Any? = null,
+                                   noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleUrlRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.OPTIONS)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -488,17 +477,18 @@ inline fun <reified M> syncOptions(
     }
 }
 
-inline fun <reified M> syncTrace(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncTrace(path: String,
+                                 tag: Any? = null,
+                                 cache: CacheMode = CacheMode.HTTP,
+                                 absolutePath: Boolean = false,
+                                 uid: Any? = null,
+                                 noinline block: SimpleUrlRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleUrlRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.TRACE)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -512,17 +502,18 @@ inline fun <reified M> syncTrace(
     }
 }
 
-inline fun <reified M> syncDelete(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncDelete(path: String,
+                                  tag: Any? = null,
+                                  cache: CacheMode = CacheMode.HTTP,
+                                  absolutePath: Boolean = false,
+                                  uid: Any? = null,
+                                  noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.DELETE)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -536,17 +527,18 @@ inline fun <reified M> syncDelete(
     }
 }
 
-inline fun <reified M> syncPut(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncPut(path: String,
+                               tag: Any? = null,
+                               cache: CacheMode = CacheMode.HTTP,
+                               absolutePath: Boolean = false,
+                               uid: Any? = null,
+                               noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.PUT)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -560,17 +552,18 @@ inline fun <reified M> syncPut(
     }
 }
 
-inline fun <reified M> syncPatch(
-        path: String,
-        tag: Any? = null,
-        cache: CacheMode = CacheMode.HTTP,
-        absolutePath: Boolean = false,
-        noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
+inline fun <reified M> syncPatch(path: String,
+                                 tag: Any? = null,
+                                 cache: CacheMode = CacheMode.HTTP,
+                                 absolutePath: Boolean = false,
+                                 uid: Any? = null,
+                                 noinline block: SimpleBodyRequest.Api.() -> Unit = {}): M {
 
     val realPath = if (absolutePath) path else (NetConfig.host + path)
 
     val request = SimpleBodyRequest.newApi(Url.newBuilder(realPath).build(), RequestMethod.PATCH)
             .tag(tag)
+            .uid(uid)
             .cacheKey(path)
             .cacheMode(cache)
 
@@ -584,33 +577,33 @@ inline fun <reified M> syncPatch(
     }
 }
 
-fun syncDownload(
-        path: String,
-        dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
-        tag: Any? = null,
-        absolutePath: Boolean = false,
-        method: RequestMethod = RequestMethod.GET,
-        block: UrlDownload.Api.() -> Unit = {}): String {
+fun syncDownload(path: String,
+                 dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
+                 tag: Any? = null,
+                 absolutePath: Boolean = false,
+                 method: RequestMethod = RequestMethod.GET,
+                 uid: Any? = null,
+                 block: UrlDownload.Api.() -> Unit = {}): String {
     if (method == RequestMethod.POST || method == RequestMethod.DELETE || method == RequestMethod.PUT || method == RequestMethod.PATCH) {
         throw UnsupportedOperationException("You should use [syncDownloadBody] function")
     }
     val realPath = if (absolutePath) path else (NetConfig.host + path)
-    val download = UrlDownload.newApi(Url.newBuilder(realPath).build(), method).directory(dir).tag(tag)
+    val download = UrlDownload.newApi(Url.newBuilder(realPath).build(), method).directory(dir).tag(tag).uid(uid)
     return download.apply(block).perform()
 }
 
-fun syncDownloadBody(
-        path: String,
-        dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
-        tag: Any? = null,
-        absolutePath: Boolean = false,
-        method: RequestMethod = RequestMethod.GET,
-        block: BodyDownload.Api.() -> Unit = {}): String {
+fun syncDownloadBody(path: String,
+                     dir: String = NetConfig.app.externalCacheDir!!.absolutePath,
+                     tag: Any? = null,
+                     absolutePath: Boolean = false,
+                     method: RequestMethod = RequestMethod.GET,
+                     uid: Any? = null,
+                     block: BodyDownload.Api.() -> Unit = {}): String {
     if (method == RequestMethod.GET || method == RequestMethod.HEAD || method == RequestMethod.OPTIONS || method == RequestMethod.TRACE) {
         throw UnsupportedOperationException("You should use [syncDownload] function")
     }
     val realPath = if (absolutePath) path else (NetConfig.host + path)
-    val download = BodyDownload.newApi(Url.newBuilder(realPath).build(), method).directory(dir).tag(tag)
+    val download = BodyDownload.newApi(Url.newBuilder(realPath).build(), method).directory(dir).tag(tag).uid(uid)
     return download.apply(block).perform()
 }
 

+ 6 - 9
net/src/main/java/com/drake/net/NetConfig.kt

@@ -64,8 +64,8 @@ object NetConfig {
             is RequestParamsException,
             is ResponseException,
             is NullPointerException -> onError(
-                this
-            )
+                    this
+                                              )
             else -> printStackTrace()
         }
     }
@@ -122,14 +122,11 @@ fun KalleConfig.Builder.onDialog(block: (DialogCoroutineScope.(context: Fragment
     NetConfig.defaultDialog = block
 }
 
-fun KalleConfig.Builder.cacheEnabled(
-    path: String = NetConfig.app.cacheDir.absolutePath,
-    password: String = "cache"
-) {
+fun KalleConfig.Builder.cacheEnabled(path: String = NetConfig.app.cacheDir.absolutePath,
+                                     password: String = "cache") {
     val cacheStore = DiskCacheStore.newBuilder(path)
-        .password(password)
-        .build()
-
+            .password(password)
+            .build()
     cacheStore(cacheStore)
 }
 

+ 9 - 12
net/src/main/java/com/drake/net/convert/DefaultConvert.kt

@@ -28,19 +28,16 @@ import java.lang.reflect.Type
  * @param message  错误信息在Json中的字段名
  */
 @Suppress("UNCHECKED_CAST")
-abstract class DefaultConvert(
-    val success: String = "0",
-    val code: String = "code",
-    val message: String = "msg"
-) : Converter {
+abstract class DefaultConvert(val success: String = "0",
+                              val code: String = "code",
+                              val message: String = "msg") : Converter {
+
+    override fun <S, F> convert(succeed: Type,
+                                failed: Type,
+                                request: Request,
+                                response: Response,
+                                result: Result<S, F>) {
 
-    override fun <S, F> convert(
-            succeed: Type,
-            failed: Type,
-            request: Request,
-            response: Response,
-            result: Result<S, F>
-    ) {
         val body = response.body().string()
         val code = response.code()
 

+ 4 - 4
net/src/main/java/com/drake/net/error/NetCancellationException.kt

@@ -7,15 +7,15 @@
 
 package com.drake.net.error
 
-import com.yanzhenjie.kalle.Canceler
+import com.yanzhenjie.kalle.NetDispose
 import kotlinx.coroutines.CoroutineExceptionHandler
 import kotlinx.coroutines.CoroutineScope
 import java.util.concurrent.CancellationException
 
-class NetCancellationException(coroutineScope: CoroutineScope, message: String? = null) :
-        CancellationException(message) {
+class NetCancellationException(coroutineScope: CoroutineScope,
+                               message: String? = null) : CancellationException(message) {
     init {
-        Canceler.cancel(coroutineScope.coroutineContext[CoroutineExceptionHandler])
+        NetDispose.dispose(coroutineScope.coroutineContext[CoroutineExceptionHandler])
     }
 }
 

+ 2 - 4
net/src/main/java/com/drake/net/error/RequestParamsException.kt

@@ -13,7 +13,5 @@ import com.yanzhenjie.kalle.exception.NetException
 /**
  * 404
  */
-class RequestParamsException(
-    val code: Int,
-    request: Request
-) : NetException(request, code.toString())
+class RequestParamsException(val code: Int,
+                             request: Request) : NetException(request, code.toString())

+ 3 - 5
net/src/main/java/com/drake/net/error/ResponseException.kt

@@ -16,8 +16,6 @@ import com.yanzhenjie.kalle.exception.NetException
  * @param code 网络请求错误码
  * @param tag 应对错误码判断为错时但是后端又返回了需要使用的数据(建议后端修改). 一般在Convert中设置数据
  */
-class ResponseException(
-    val code: Int,
-    val msg: String,
-    request: Request
-) : NetException(request, "$code $msg")
+class ResponseException(val code: Int,
+                        val msg: String,
+                        request: Request) : NetException(request, "$code $msg")

+ 2 - 4
net/src/main/java/com/drake/net/error/ServerResponseException.kt

@@ -13,7 +13,5 @@ import com.yanzhenjie.kalle.exception.NetException
 /**
  * 500
  */
-class ServerResponseException(
-    val code: Int,
-    request: Request
-) : NetException(request, code.toString())
+class ServerResponseException(val code: Int,
+                              request: Request) : NetException(request, code.toString())

+ 4 - 7
net/src/main/java/com/drake/net/scope/AndroidScope.kt

@@ -18,11 +18,8 @@ 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) : CoroutineScope {
 
     init {
         lifecycleOwner?.lifecycle?.addObserver(object : LifecycleEventObserver {
@@ -96,8 +93,8 @@ open class AndroidScope(
         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))
 
 }
 

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

@@ -30,11 +30,9 @@ import com.drake.net.R
  * @param cancelable 是否允许用户取消对话框
  */
 @Suppress("DEPRECATION")
-class DialogCoroutineScope(
-    val activity: FragmentActivity,
-    var dialog: Dialog? = null,
-    val cancelable: Boolean = true
-) : NetCoroutineScope(), LifecycleObserver {
+class DialogCoroutineScope(val activity: FragmentActivity,
+                           var dialog: Dialog? = null,
+                           val cancelable: Boolean = true) : NetCoroutineScope(), LifecycleObserver {
 
     init {
         activity.lifecycle.addObserver(this)

+ 5 - 9
net/src/main/java/com/drake/net/scope/NetCoroutineScope.kt

@@ -11,7 +11,7 @@ import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleEventObserver
 import androidx.lifecycle.LifecycleOwner
 import com.drake.net.NetConfig
-import com.yanzhenjie.kalle.Canceler
+import com.yanzhenjie.kalle.NetDispose
 import kotlinx.coroutines.CancellationException
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
@@ -36,10 +36,8 @@ open class NetCoroutineScope() : AndroidScope() {
 
     var animate: Boolean = false
 
-    constructor(
-            lifecycleOwner: LifecycleOwner,
-            lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY
-               ) : this() {
+    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()
@@ -47,9 +45,7 @@ open class NetCoroutineScope() : AndroidScope() {
         })
     }
 
-    override fun launch(
-            block: suspend CoroutineScope.() -> Unit
-                       ): NetCoroutineScope {
+    override fun launch(block: suspend CoroutineScope.() -> Unit): NetCoroutineScope {
         launch(EmptyCoroutineContext) {
             start()
             if (onCache != null && isReadCache) {
@@ -104,7 +100,7 @@ open class NetCoroutineScope() : AndroidScope() {
     }
 
     override fun cancel(cause: CancellationException?) {
-        Canceler.cancel(uid)
+        NetDispose.dispose(uid)
         super.cancel(cause)
     }
 }

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

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

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

@@ -11,7 +11,6 @@ import android.view.View
 import com.drake.net.NetConfig
 import com.drake.statelayout.StateLayout
 import kotlinx.coroutines.CancellationException
-import kotlinx.coroutines.cancel
 
 /**
  * 缺省页作用域

+ 7 - 12
net/src/main/java/com/drake/net/utils/JetPackUtils.kt

@@ -43,11 +43,9 @@ fun <M> LifecycleOwner.observe(liveData: LiveData<M>?, block: M?.() -> Unit) {
  * 监听数据库
  */
 @UseExperimental(ExperimentalCoroutinesApi::class)
-fun <T> Flow<List<T>>.listen(
-    lifecycleOwner: LifecycleOwner? = null,
-    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
-    block: (List<T>) -> Unit
-) {
+fun <T> Flow<List<T>>.listen(lifecycleOwner: LifecycleOwner? = null,
+                             lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY,
+                             block: (List<T>) -> Unit) {
     AndroidScope(lifecycleOwner, lifeEvent).launch {
         distinctUntilChanged().collect { data ->
             withMain {
@@ -65,15 +63,12 @@ inline fun <reified M : ViewModel> ViewModelStoreOwner.getViewModel(): M {
 
 inline fun <reified M : ViewModel> FragmentActivity.getSavedModel(): M {
     return ViewModelProvider(
-        this,
-        SavedStateViewModelFactory(application, this)
-    ).get(M::class.java)
+            this,
+            SavedStateViewModelFactory(application, this)
+                            ).get(M::class.java)
 }
 
 
 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)
 }

+ 4 - 8
net/src/main/java/com/drake/net/utils/SuspendUtils.kt

@@ -16,17 +16,13 @@ import kotlinx.coroutines.withContext
 
 // <editor-fold desc="切换调度器">
 
-suspend fun <T> withMain(block: suspend CoroutineScope.() -> T) =
-    withContext(Dispatchers.Main, block)
+suspend fun <T> withMain(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Main, block)
 
-suspend fun <T> withIO(block: suspend CoroutineScope.() -> T) =
-    withContext(Dispatchers.IO, block)
+suspend fun <T> withIO(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.IO, block)
 
-suspend fun <T> withDefault(block: suspend CoroutineScope.() -> T) =
-    withContext(Dispatchers.Default, block)
+suspend fun <T> withDefault(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Default, block)
 
-suspend fun <T> withUnconfined(block: suspend CoroutineScope.() -> T) =
-    withContext(Dispatchers.Unconfined, block)
+suspend fun <T> withUnconfined(block: suspend CoroutineScope.() -> T) = withContext(Dispatchers.Unconfined, block)
 
 // </editor-fold>
 

+ 6 - 14
net/src/main/java/com/drake/net/utils/ThrottleClickListener.kt

@@ -10,31 +10,23 @@ package com.drake.net.utils
 import android.view.View
 import java.util.concurrent.TimeUnit
 
-internal fun View.throttleClick(
-    interval: Long = 500,
-    unit: TimeUnit = TimeUnit.MILLISECONDS,
-    block: View.() -> Unit
-) {
+internal fun View.throttleClick(interval: Long = 500,
+                                unit: TimeUnit = TimeUnit.MILLISECONDS,
+                                block: View.() -> Unit) {
     setOnClickListener(ThrottleClickListener(interval, unit, block))
 }
 
-internal class ThrottleClickListener(
-    private val interval: Long = 500,
-    private val unit: TimeUnit = TimeUnit.MILLISECONDS,
-    private var block: View.() -> Unit
-) :
-    View.OnClickListener {
+internal class ThrottleClickListener(private val interval: Long = 500,
+                                     private val unit: TimeUnit = TimeUnit.MILLISECONDS,
+                                     private var block: View.() -> Unit) : View.OnClickListener {
 
     private var lastTime: Long = 0
 
     override fun onClick(v: View) {
-
         val currentTime = System.currentTimeMillis()
-
         if (currentTime - lastTime > unit.toMillis(interval)) {
             lastTime = currentTime
             block(v)
         }
-
     }
 }