Pārlūkot izejas kodu

| Convert增加Request参数便于在转换器中定位接口
| 所有异常都能追踪到位置, 通过Request.location()

drake 5 gadi atpakaļ
vecāks
revīzija
9ddd32a769

+ 40 - 32
README.md

@@ -6,10 +6,12 @@
 
 本项目为Android项目中的所有的异步任务和网络请求而生
 
+The project is supported by [JetBrains](https://www.jetbrains.com/), Best IDE to developer <img src="https://tva1.sinaimg.cn/large/006tNbRwgy1gaskr305czj30u00wjtcz.jpg" alt="jetbrains" style="zoom:8%;" />
+
 
 
 1.0+ 版本为RxKotlin实现
-2.0+ 版本开始引入Kotlin协程特性, 开发者无需掌握协程也可以使用, 两个版本存在Api变动需要手动迁移
+2.0+ 版本开始引入Kotlin协程特性, 开发者无需掌握协程也可以使用, 两个版本存在Api变动需要手动迁移 
 
 
 
@@ -217,6 +219,41 @@ class App : Application() {
 }
 ```
 
+
+
+### 初始化配置
+
+在初始化的时候可以选择配置网络请求
+
+```kotlin
+initNet("http://192.168.2.1") {
+
+  // 默认错误处理
+  onError {
+
+  }
+
+  // PageObserver 默认错误处理
+  onPageError {
+
+  }
+
+  // 默认加载对话框
+  onDialog {
+
+    ProgressDialog(it)
+  }
+
+  converter(object : DefaultConverter() {
+    override fun <S> convert(succeed: Type, body: String): S? {
+      return Moshi.Builder().build().adapter<S>(succeed).fromJson(body)
+    }
+  })
+}
+```
+
+
+
 ### 错误信息
 
 第一种覆盖`onError`函数
@@ -290,38 +327,9 @@ internal var onError: Throwable.() -> Unit = {
 
 
 
-### 初始化配置
-
-在初始化的时候可以选择配置网络请求
-
-```kotlin
-initNet("http://192.168.2.1") {
-
-  // 默认错误处理
-  onError {
-
-  }
-
-  // PageObserver 默认错误处理
-  onPageError {
-
-  }
-
-  // 默认加载对话框
-  onDialog {
-
-    ProgressDialog(it)
-  }
-
-  converter(object : DefaultConverter() {
-    override fun <S> convert(succeed: Type, body: String): S? {
-      return Moshi.Builder().build().adapter<S>(succeed).fromJson(body)
-    }
-  })
-}
-```
+### 异常日志
 
-## 
+网络请求的每个异常都会被自动打印到LogCat, 并且附带位置信息: location, 默认为url. 可以在拦截器中通过Request.location()设置
 
 ## 作用域
 

+ 12 - 0
kalle/src/main/java/com/yanzhenjie/kalle/Request.java

@@ -37,6 +37,18 @@ public abstract class Request {
     private final int mReadTimeout;
     private final Object mTag;
 
+    private String location;
+
+    public void location(String location) {
+        this.location = location;
+    }
+
+    public String location() {
+        if (location != null) {
+            return location;
+        } else return url().toString();
+    }
+
     protected <T extends Api<T>> Request(Api<T> api) {
         this.mMethod = api.mMethod;
         this.mHeaders = api.mHeaders;

+ 2 - 0
kalle/src/main/java/com/yanzhenjie/kalle/Response.java

@@ -28,6 +28,7 @@ public final class Response implements Closeable {
     private final int mCode;
     private final Headers mHeaders;
     private final ResponseBody mBody;
+
     private Response(Builder builder) {
         this.mCode = builder.mCode;
         this.mHeaders = builder.mHeaders;
@@ -38,6 +39,7 @@ public final class Response implements Closeable {
         return new Builder();
     }
 
+
     /**
      * Get the mCode of response.
      */

+ 12 - 12
kalle/src/main/java/com/yanzhenjie/kalle/connect/http/ConnectInterceptor.java

@@ -86,7 +86,7 @@ class ConnectInterceptor implements Interceptor {
             headers.set(KEY_CONTENT_LENGTH, Long.toString(body.contentLength()));
             headers.set(KEY_CONTENT_TYPE, body.contentType());
             mConnection = connect(request);
-            writeBody(body);
+            writeBody(request);
         } else {
             mConnection = connect(request);
         }
@@ -112,7 +112,7 @@ class ConnectInterceptor implements Interceptor {
      */
     private Connection connect(Request request) throws ConnectException {
         if (!mNetwork.isAvailable())
-            throw new NetworkError(String.format("Network Unavailable: %1$s.", request.url()));
+            throw new NetworkError(String.format("Network Unavailable: %1$s.", request.location()));
 
         try {
             Headers headers = request.headers();
@@ -123,25 +123,25 @@ class ConnectInterceptor implements Interceptor {
             headers.set(KEY_HOST, uri.getHost());
             return mFactory.connect(request);
         } catch (URISyntaxException e) {
-            throw new URLError(String.format("The url syntax error: %1$s.", request.url()), e);
+            throw new URLError(String.format("The url syntax error: %1$s.", request.location()), e);
         } catch (MalformedURLException e) {
-            throw new URLError(String.format("The url is malformed: %1$s.", request.url()), e);
+            throw new URLError(String.format("The url is malformed: %1$s.", request.location()), e);
         } catch (UnknownHostException e) {
-            throw new HostError(String.format("Hostname can not be resolved: %1$s.", request.url()), e);
+            throw new HostError(String.format("Hostname can not be resolved: %1$s.", request.location()), e);
         } catch (SocketTimeoutException e) {
-            throw new ConnectTimeoutError(String.format("Connect time out: %1$s.", request.url()), e);
+            throw new ConnectTimeoutError(String.format("Connect time out: %1$s.", request.location()), e);
         } catch (Exception e) {
-            throw new ConnectException(String.format("An unknown exception: %1$s.", request.url()), e);
+            throw new ConnectException(String.format("An unknown exception: %1$s.", request.location()), e);
         }
     }
 
-    private void writeBody(RequestBody body) throws WriteException {
+    private void writeBody(Request request) throws WriteException {
         try {
             OutputStream stream = mConnection.getOutputStream();
-            body.writeTo(IOUtils.toBufferedOutputStream(stream));
+            request.body().writeTo(IOUtils.toBufferedOutputStream(stream));
             IOUtils.closeQuietly(stream);
         } catch (Exception e) {
-            throw new WriteException(e);
+            throw new WriteException(request.location(), e);
         }
     }
 
@@ -158,9 +158,9 @@ class ConnectInterceptor implements Interceptor {
             ResponseBody body = new StreamBody(contentType, mConnection.getInputStream());
             return Response.newBuilder().code(code).headers(headers).body(body).build();
         } catch (SocketTimeoutException e) {
-            throw new ReadTimeoutError(String.format("Read data time out: %1$s.", request.url()), e);
+            throw new ReadTimeoutError(String.format("Read data time out: %1$s.", request.location()), e);
         } catch (Exception e) {
-            throw new ReadException(e);
+            throw new ReadException(request.location(), e);
         }
     }
 

+ 1 - 1
kalle/src/main/java/com/yanzhenjie/kalle/download/BasicWorker.java

@@ -90,7 +90,7 @@ public abstract class BasicWorker<T extends Download> implements Callable<String
             }
 
             if (!mPolicy.allowDownload(code, comeHeaders)) {
-                throw new DownloadError(code, comeHeaders, "The download policy prohibits the program from continuing to download.");
+                throw new DownloadError(code, comeHeaders, "The download policy prohibits the program from continuing to download: " + mDownload.request().location());
             }
 
             File file = new File(mDirectory, mFileName);

+ 6 - 0
kalle/src/main/java/com/yanzhenjie/kalle/download/BodyDownload.java

@@ -17,6 +17,7 @@ package com.yanzhenjie.kalle.download;
 
 import com.yanzhenjie.kalle.BodyRequest;
 import com.yanzhenjie.kalle.Canceller;
+import com.yanzhenjie.kalle.Request;
 import com.yanzhenjie.kalle.RequestMethod;
 import com.yanzhenjie.kalle.Url;
 
@@ -41,6 +42,11 @@ public class BodyDownload extends BodyRequest implements Download {
         return new BodyDownload.Api(url, method);
     }
 
+    @Override
+    public Request request() {
+        return this;
+    }
+
     @Override
     public String directory() {
         return mDirectory;

+ 3 - 0
kalle/src/main/java/com/yanzhenjie/kalle/download/Download.java

@@ -16,6 +16,7 @@
 package com.yanzhenjie.kalle.download;
 
 import com.yanzhenjie.kalle.Headers;
+import com.yanzhenjie.kalle.Request;
 import com.yanzhenjie.kalle.Url;
 
 /**
@@ -23,6 +24,8 @@ import com.yanzhenjie.kalle.Url;
  */
 public interface Download {
 
+    Request request();
+
     /**
      * Get the file download address.
      */

+ 6 - 0
kalle/src/main/java/com/yanzhenjie/kalle/download/UrlDownload.java

@@ -16,6 +16,7 @@
 package com.yanzhenjie.kalle.download;
 
 import com.yanzhenjie.kalle.Canceller;
+import com.yanzhenjie.kalle.Request;
 import com.yanzhenjie.kalle.RequestMethod;
 import com.yanzhenjie.kalle.Url;
 import com.yanzhenjie.kalle.UrlRequest;
@@ -41,6 +42,11 @@ public class UrlDownload extends UrlRequest implements Download {
         return new UrlDownload.Api(url, method);
     }
 
+    @Override
+    public Request request() {
+        return this;
+    }
+
     @Override
     public String directory() {
         return mDirectory;

+ 3 - 3
kalle/src/main/java/com/yanzhenjie/kalle/simple/BasicWorker.java

@@ -133,7 +133,7 @@ abstract class BasicWorker<T extends SimpleRequest, Succeed, Failed>
                 if (cache != null) {
                     return buildResponse(cache.getCode(), cache.getHeaders(), cache.getBody());
                 }
-                throw new NoCacheError("No cache found.");
+                throw new NoCacheError("No cache found: " + mRequest.request().location());
             }
             case READ_CACHE_NO_THEN_NETWORK:
             case READ_CACHE_NO_THEN_HTTP: {
@@ -286,11 +286,11 @@ abstract class BasicWorker<T extends SimpleRequest, Succeed, Failed>
 
     private SimpleResponse<Succeed, Failed> buildSimpleResponse(Response response, boolean cache) throws IOException {
         try {
-            return mConverter.convert(mSucceed, mFailed, response, cache);
+            return mConverter.convert(mSucceed, mFailed, mRequest.request(), response, cache);
         } catch (IOException e) {
             throw e;
         } catch (Exception e) {
-            throw new ParseError("An exception occurred while parsing the data.", e);
+            throw new ParseError("An exception occurred while parsing the data: " + mRequest.request().location(), e);
         }
     }
 }

+ 3 - 2
kalle/src/main/java/com/yanzhenjie/kalle/simple/Converter.java

@@ -15,6 +15,7 @@
  */
 package com.yanzhenjie.kalle.simple;
 
+import com.yanzhenjie.kalle.Request;
 import com.yanzhenjie.kalle.Response;
 
 import java.lang.reflect.Type;
@@ -29,7 +30,7 @@ public interface Converter {
      */
     Converter DEFAULT = new Converter() {
         @Override
-        public <S, F> SimpleResponse<S, F> convert(Type succeed, Type failed, Response response, boolean fromCache) throws Exception {
+        public <S, F> SimpleResponse<S, F> convert(Type succeed, Type failed, Request request, Response response, boolean fromCache) throws Exception {
             S succeedData = null;
 
             if (succeed == String.class) succeedData = (S) response.body().string();
@@ -55,5 +56,5 @@ public interface Converter {
      * @return {@link SimpleResponse}
      * @throws Exception to prevent accidents.
      */
-    <S, F> SimpleResponse<S, F> convert(Type succeed, Type failed, Response response, boolean fromCache) throws Exception;
+    <S, F> SimpleResponse<S, F> convert(Type succeed, Type failed, Request request, Response response, boolean fromCache) throws Exception;
 }

+ 6 - 0
kalle/src/main/java/com/yanzhenjie/kalle/simple/SimpleBodyRequest.java

@@ -19,6 +19,7 @@ import android.text.TextUtils;
 
 import com.yanzhenjie.kalle.BodyRequest;
 import com.yanzhenjie.kalle.Canceller;
+import com.yanzhenjie.kalle.Request;
 import com.yanzhenjie.kalle.RequestMethod;
 import com.yanzhenjie.kalle.Url;
 import com.yanzhenjie.kalle.simple.cache.CacheMode;
@@ -44,6 +45,11 @@ public class SimpleBodyRequest extends BodyRequest implements SimpleRequest {
         this.mConverter = api.mConverter;
     }
 
+    @Override
+    public Request request() {
+        return this;
+    }
+
     public static SimpleBodyRequest.Api newApi(Url url, RequestMethod method) {
         return new SimpleBodyRequest.Api(url, method);
     }

+ 3 - 0
kalle/src/main/java/com/yanzhenjie/kalle/simple/SimpleRequest.java

@@ -16,6 +16,7 @@
 package com.yanzhenjie.kalle.simple;
 
 import com.yanzhenjie.kalle.Headers;
+import com.yanzhenjie.kalle.Request;
 import com.yanzhenjie.kalle.Url;
 import com.yanzhenjie.kalle.simple.cache.CacheMode;
 
@@ -47,4 +48,6 @@ public interface SimpleRequest {
      * Get converter.
      */
     Converter converter();
+
+    Request request();
 }

+ 6 - 0
kalle/src/main/java/com/yanzhenjie/kalle/simple/SimpleUrlRequest.java

@@ -18,6 +18,7 @@ package com.yanzhenjie.kalle.simple;
 import android.text.TextUtils;
 
 import com.yanzhenjie.kalle.Canceller;
+import com.yanzhenjie.kalle.Request;
 import com.yanzhenjie.kalle.RequestMethod;
 import com.yanzhenjie.kalle.Url;
 import com.yanzhenjie.kalle.UrlRequest;
@@ -48,6 +49,11 @@ public class SimpleUrlRequest extends UrlRequest implements SimpleRequest {
         return new SimpleUrlRequest.Api(url, method);
     }
 
+    @Override
+    public Request request() {
+        return this;
+    }
+
     @Override
     public CacheMode cacheMode() {
         return mCacheMode;

+ 2 - 1
net/src/main/java/com/drake/net/convert/DefaultConvert.kt

@@ -11,6 +11,7 @@ package com.drake.net.convert
 
 import com.drake.net.error.RequestParamsException
 import com.drake.net.error.ServerResponseException
+import com.yanzhenjie.kalle.Request
 import com.yanzhenjie.kalle.Response
 import com.yanzhenjie.kalle.simple.Converter
 import com.yanzhenjie.kalle.simple.SimpleResponse
@@ -37,6 +38,7 @@ abstract class DefaultConvert(
     override fun <S, F> convert(
         succeed: Type,
         failed: Type,
+        request: Request,
         response: Response,
         fromCache: Boolean
     ): SimpleResponse<S, F> {
@@ -46,7 +48,6 @@ abstract class DefaultConvert(
         val body = response.body().string()
         var code = response.code()
 
-
         when {
             code in 200..299 -> {
                 val jsonObject = JSONObject(body)

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

@@ -18,14 +18,14 @@ import kotlin.coroutines.EmptyCoroutineContext
  * 异步协程作用域
  */
 @Suppress("unused", "MemberVisibilityCanBePrivate", "NAME_SHADOWING")
-open class AndroidScope() : CoroutineScope {
+open class AndroidScope(
+    lifecycleOwner: LifecycleOwner? = null,
+    lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY
+) : CoroutineScope {
 
 
-    constructor(
-        lifecycleOwner: LifecycleOwner,
-        lifeEvent: Lifecycle.Event = Lifecycle.Event.ON_DESTROY
-    ) : this() {
-        lifecycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
+    init {
+        lifecycleOwner?.lifecycle?.addObserver(object : LifecycleEventObserver {
             override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
                 if (lifeEvent == event) {
                     cancel()

+ 15 - 0
net/src/main/java/com/drake/net/utils/ScopeUtils.kt

@@ -17,6 +17,9 @@ import com.drake.net.scope.*
 import com.drake.statelayout.StateLayout
 import com.scwang.smart.refresh.layout.SmartRefreshLayout
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.InternalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.FlowCollector
 
 /**
  * 作用域内部全在主线程
@@ -138,6 +141,18 @@ fun LifecycleOwner.scopeNetLife(
 }
 
 
+@UseExperimental(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 {
+    this@scope.collect(object : FlowCollector<T> {
+        override suspend fun emit(value: T) = action(value)
+    })
+}
+
+
 
 
 

+ 1 - 1
sample/src/main/java/com/drake/net/sample/MainActivity.kt

@@ -23,7 +23,7 @@ class MainActivity : AppCompatActivity() {
                 Log.d("日志", "(MainActivity.kt:50)    网络")
 
                 val data = get<String>(
-                    "https://raw.githubusercontent.com/liangjingkanji/BRV/master/README.md",
+                    "https://raw.githusercontent.com/liangjingkanji/BRV/master/README.md",
                     cache = CacheMode.NETWORK_YES_THEN_WRITE_CACHE,
                     absolutePath = true
                 )