Browse Source

+ onPageError
+ PageRefreshLayout自动展示缺省页
* RefreshObserver 默认关闭上拉加载
* README

drake 5 năm trước cách đây
mục cha
commit
d3f28cfcad

+ 116 - 38
README.md

@@ -54,14 +54,14 @@ allprojects {
 module of build.gradle
 
 ```groovy
-implementation 'com.github.liangjingkanji:Net:1.1.5'
+implementation 'com.github.liangjingkanji:Net:1.1.6'
 ```
 
 
 
 
 
-## 初始化
+## 初始化和配置
 
 ```kotlin
 class App : Application() {
@@ -71,11 +71,6 @@ class App : Application() {
 
         initNet("主机名"){
 
-            // 替换默认的错误处理(可选)
-            onError {
-
-            }
-
             // 转换器, 也可以自己实现Convert或者复写DefaultConverter
             converter(object : DefaultConverter() {
                 override fun <S> convert(succeed: Type, body: String): S? {
@@ -88,8 +83,6 @@ class App : Application() {
 }
 ```
 
-
-
 ### 错误信息
 
 第一种覆盖`onError`函数
@@ -101,29 +94,32 @@ class App : Application() {
 这里使用的系统默认的Toast进行错误信息提示用户, 你可以复写然后实现自己的吐司提示.
 
 ```kotlin
-    var onError: Throwable.() -> Unit = {
-
-        val message = when (this) {
-            is NetworkError -> app.getString(R.string.network_error)
-            is URLError -> app.getString(R.string.url_error)
-            is HostError -> app.getString(R.string.host_error)
-            is ConnectTimeoutError -> app.getString(R.string.connect_timeout_error)
-            is ConnectException -> app.getString(R.string.connect_exception)
-            is WriteException -> app.getString(R.string.write_exception)
-            is ReadTimeoutError -> app.getString(R.string.read_timeout_error)
-            is DownloadError -> app.getString(R.string.download_error)
-            is NoCacheError -> app.getString(R.string.no_cache_error)
-            is ParseError -> app.getString(R.string.parse_error)
-            is ReadException -> app.getString(R.string.read_exception)
-            is ResponseException -> msg
-            else -> {
-                printStackTrace()
-                app.getString(R.string.other_error)
-            }
-        }
-
-        Toast.makeText(app, message, Toast.LENGTH_SHORT).show()
+internal var onError: Throwable.() -> Unit = {
+
+  val message = when (this) {
+    is NetworkError -> app.getString(R.string.network_error)
+    is URLError -> app.getString(R.string.url_error)
+    is HostError -> app.getString(R.string.host_error)
+    is ConnectTimeoutError -> app.getString(R.string.connect_timeout_error)
+    is ConnectException -> app.getString(R.string.connect_exception)
+    is WriteException -> app.getString(R.string.write_exception)
+    is ReadTimeoutError -> app.getString(R.string.read_timeout_error)
+    is DownloadError -> app.getString(R.string.download_error)
+    is NoCacheError -> app.getString(R.string.no_cache_error)
+    is ReadException -> app.getString(R.string.read_exception)
+    is ParseError -> app.getString(R.string.parse_error)
+    is ParseJsonException -> app.getString(R.string.parse_json_error)
+    is RequestParamsException -> app.getString(R.string.request_error)
+    is ServerResponseException -> app.getString(R.string.server_error)
+    is ResponseException -> msg
+    else -> {
+      printStackTrace()
+      app.getString(R.string.other_error)
     }
+  }
+
+  Toast.makeText(app, message, Toast.LENGTH_SHORT).show()
+}
 ```
 
 
@@ -138,7 +134,6 @@ class App : Application() {
 <resources>
     <string name="app_name">Net</string>
 
-
     <!--网络请求异常-->
     <string name="network_error">当前网络不可用</string>
     <string name="url_error">请求资源地址错误</string>
@@ -151,20 +146,47 @@ class App : Application() {
     <string name="no_cache_error">读取缓存错误</string>
     <string name="parse_error">解析数据时发生异常</string>
     <string name="read_exception">读取数据错误</string>
-    <string name="other_error">服务器未响应</string>
-
-    <!--DefaultConverter-->
-    <string name="parse_data_error">解析数据错误</string>
     <string name="parse_json_error">解析JSON错误</string>
     <string name="request_error">请求参数错误</string>
     <string name="server_error">服务响应错误</string>
-
+    <string name="other_error">服务器未响应</string>
 
 </resources>
 ```
 
 
 
+### 初始化配置
+
+在初始化的时候可以选择配置网络请求
+
+```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)
+    }
+  })
+}
+```
+
 
 
 ## 请求方式
@@ -290,6 +312,41 @@ post<Model>(""){
 
 
 
+某些情况存在一些页面仅仅需要下拉刷新, 不需要分页/缺省页/上拉加载, 例如用户中心的刷新. 这个时候我们应该使用`refresh`函数而不是`page`.
+
+```
+post<Model>(""){
+  file("file", File("path"))
+}.refresh(smartRefreshLayout) {
+
+}
+```
+
+refresh函数
+
+```kotlin
+/**
+ * 自动结束下拉加载
+ * @receiver Observable<M>
+ * @param pageRefreshLayout SmartRefreshLayout
+ * @param loadMore 是否启用上拉加载
+ * @param block (M) -> UnitUtils
+ */
+fun <M> Observable<M>.refresh(
+    pageRefreshLayout: PageRefreshLayout,
+    loadMore: Boolean = false,
+    block: RefreshObserver<M>.(M) -> Unit
+) {
+    subscribe(object : RefreshObserver<M>(pageRefreshLayout, loadMore) {
+        override fun onNext(t: M) {
+            block(t)
+        }
+    })
+}
+```
+
+
+
 ## 缺省页
 
 需要引入第三方库: [StateLayout](https://github.com/liangjingkanji/StateLayout) (如果已经引入BRV可以不再引入)
@@ -315,4 +372,25 @@ post<Model>(""){
 
 会根据参数的不同而给不同的对象添加缺省页状态
 
-## 
+##重写Observer
+
+无论是`page/refresh/net/dialog`这些函数本身都是快速创建Observer的扩展函数而已, 如果你需要拿到Observer的onError/onCompleted等回调请自己创建匿名类或者继承.
+
+
+
+例如查看page源码即可看到只是创建一个Observer订阅而已
+
+```kotlin
+fun <M> Observable<M>.page(
+    pageRefreshLayout: PageRefreshLayout,
+    block: PageObserver<M>.(M) -> Unit
+) {
+    subscribe(object : PageObserver<M>(pageRefreshLayout) {
+        override fun onNext(t: M) {
+            block(t)
+        }
+    })
+}
+```
+
+所有扩展订阅函数的都在`ObserverUtils`类中

+ 2 - 0
net/src/main/java/com/drake/net/Net.kt

@@ -5,6 +5,8 @@
  * Date:9/16/19 12:54 AM
  */
 
+@file:Suppress("unused")
+
 package com.drake.net
 
 import com.drake.net.error.ResponseException

+ 40 - 4
net/src/main/java/com/drake/net/NetConfig.kt

@@ -5,11 +5,21 @@
  * Date:9/16/19 12:54 AM
  */
 
+@file:Suppress("unused")
+
 package com.drake.net
 
 import android.app.Application
+import android.app.Dialog
 import android.widget.Toast
+import androidx.fragment.app.FragmentActivity
+import com.drake.brv.PageRefreshLayout
+import com.drake.net.error.ParseJsonException
+import com.drake.net.error.RequestParamsException
 import com.drake.net.error.ResponseException
+import com.drake.net.error.ServerResponseException
+import com.drake.net.observer.DialogObserver
+import com.drake.net.observer.PageObserver
 import com.yanzhenjie.kalle.Kalle
 import com.yanzhenjie.kalle.KalleConfig
 import com.yanzhenjie.kalle.exception.*
@@ -20,7 +30,7 @@ object NetConfig {
     lateinit var host: String
     lateinit var app: Application
 
-    var onError: Throwable.() -> Unit = {
+    internal var onError: Throwable.() -> Unit = {
 
         val message = when (this) {
             is NetworkError -> app.getString(R.string.network_error)
@@ -32,8 +42,11 @@ object NetConfig {
             is ReadTimeoutError -> app.getString(R.string.read_timeout_error)
             is DownloadError -> app.getString(R.string.download_error)
             is NoCacheError -> app.getString(R.string.no_cache_error)
-            is ParseError -> app.getString(R.string.parse_error)
             is ReadException -> app.getString(R.string.read_exception)
+            is ParseError -> app.getString(R.string.parse_error)
+            is ParseJsonException -> app.getString(R.string.parse_json_error)
+            is RequestParamsException -> app.getString(R.string.request_error)
+            is ServerResponseException -> app.getString(R.string.server_error)
             is ResponseException -> msg
             else -> {
                 printStackTrace()
@@ -43,6 +56,7 @@ object NetConfig {
 
         Toast.makeText(app, message, Toast.LENGTH_SHORT).show()
     }
+
 }
 
 
@@ -55,9 +69,31 @@ fun Application.initNet(host: String, block: KalleConfig.Builder.() -> Unit = {}
 }
 
 
-// 处理错误信息
-@Suppress("unused")
+/**
+ * 处理错误信息
+ * @receiver KalleConfig.Builder
+ * @param block [@kotlin.ExtensionFunctionType] Function1<Throwable, Unit>
+ */
 fun KalleConfig.Builder.onError(block: Throwable.() -> Unit) {
     NetConfig.onError = block
 }
 
+/**
+ * 处理PageObserver的错误信息
+ * @receiver KalleConfig.Builder
+ * @param block [@kotlin.ExtensionFunctionType] Function2<Throwable, [@kotlin.ParameterName] PageRefreshLayout, Unit>
+ */
+fun KalleConfig.Builder.onPageError(block: Throwable.(pageRefreshLayout: PageRefreshLayout) -> Unit) {
+    PageObserver.onPageError = block
+}
+
+
+/**
+ * 设置DialogObserver默认弹出的加载对话框
+ * @receiver KalleConfig.Builder
+ * @param block [@kotlin.ExtensionFunctionType] Function2<DialogObserver<*>, [@kotlin.ParameterName] FragmentActivity, Dialog>
+ */
+fun KalleConfig.Builder.onDialog(block: (DialogObserver<*>.(context: FragmentActivity) -> Dialog)) {
+    DialogObserver.defaultDialog = block
+}
+

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

@@ -5,10 +5,13 @@
  * Date:9/16/19 12:54 AM
  */
 
+@file:Suppress("MemberVisibilityCanBePrivate")
+
 package com.drake.net.convert
 
-import com.drake.net.NetConfig
-import com.drake.net.R
+import com.drake.net.error.ParseJsonException
+import com.drake.net.error.RequestParamsException
+import com.drake.net.error.ServerResponseException
 import com.yanzhenjie.kalle.Response
 import com.yanzhenjie.kalle.simple.Converter
 import com.yanzhenjie.kalle.simple.SimpleResponse
@@ -55,7 +58,7 @@ abstract class DefaultConverter(
                                 succeedData = convert(succeed, body)
                             } catch (e: Exception) {
                                 e.printStackTrace()
-                                failedData = NetConfig.app.getString(R.string.parse_json_error) as F
+                                throw ParseJsonException()
                             }
                         }
                     } else {
@@ -64,11 +67,11 @@ abstract class DefaultConverter(
                     }
                 } catch (e: JSONException) {
                     e.printStackTrace()
-                    failedData = NetConfig.app.getString(R.string.parse_data_error) as F
+                    throw ParseJsonException()
                 }
             }
-            code in 400..499 -> failedData = NetConfig.app.getString(R.string.request_error) as F
-            code >= 500 -> failedData = NetConfig.app.getString(R.string.server_error) as F
+            code in 400..499 -> throw RequestParamsException()
+            code >= 500 -> throw ServerResponseException()
         }
 
         return SimpleResponse.newBuilder<S, F>().code(code)

+ 11 - 0
net/src/main/java/com/drake/net/error/ParseJsonException.kt

@@ -0,0 +1,11 @@
+/*
+ * Copyright (C) 2018, Umbrella CompanyLimited All rights reserved.
+ * Project:Net
+ * Author:Drake
+ * Date:10/28/19 8:48 PM
+ */
+
+package com.drake.net.error
+
+
+class ParseJsonException : Throwable()

+ 13 - 0
net/src/main/java/com/drake/net/error/RequestParamsException.kt

@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2018, Umbrella CompanyLimited All rights reserved.
+ * Project:Net
+ * Author:Drake
+ * Date:10/28/19 8:55 PM
+ */
+
+package com.drake.net.error
+
+/**
+ * 404
+ */
+class RequestParamsException : Throwable()

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

@@ -13,4 +13,4 @@ package com.drake.net.error
  * @property code Int 网络请求错误码
  * @constructor
  */
-class ResponseException(val msg: String, val code: Int) : Throwable()
+class ResponseException(val msg: String, val code: Int) : Throwable("code: $code, msg: $msg")

+ 13 - 0
net/src/main/java/com/drake/net/error/ServerResponseException.kt

@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2018, Umbrella CompanyLimited All rights reserved.
+ * Project:Net
+ * Author:Drake
+ * Date:10/28/19 8:55 PM
+ */
+
+package com.drake.net.error
+
+/**
+ * 500
+ */
+class ServerResponseException : Throwable()

+ 2 - 5
net/src/main/java/com/drake/net/observer/DialogObserver.kt

@@ -38,11 +38,8 @@ abstract class DialogObserver<M>(
 
     companion object {
 
-        private var defaultDialog: (DialogObserver<*>.(context: FragmentActivity) -> Dialog)? = null
-
-        fun setDefaultDialog(block: (DialogObserver<*>.(context: FragmentActivity) -> Dialog)) {
-            defaultDialog = block
-        }
+        internal var defaultDialog: (DialogObserver<*>.(context: FragmentActivity) -> Dialog)? =
+            null
     }
 
 

+ 3 - 1
net/src/main/java/com/drake/net/observer/ObserverUtils.kt

@@ -97,13 +97,15 @@ fun <M> Observable<M>.dialog(
  * 自动结束下拉加载
  * @receiver Observable<M>
  * @param pageRefreshLayout SmartRefreshLayout
+ * @param loadMore 是否启用上拉加载
  * @param block (M) -> UnitUtils
  */
 fun <M> Observable<M>.refresh(
     pageRefreshLayout: PageRefreshLayout,
+    loadMore: Boolean = false,
     block: RefreshObserver<M>.(M) -> Unit
 ) {
-    subscribe(object : RefreshObserver<M>(pageRefreshLayout) {
+    subscribe(object : RefreshObserver<M>(pageRefreshLayout, loadMore) {
         override fun onNext(t: M) {
             block(t)
         }

+ 51 - 2
net/src/main/java/com/drake/net/observer/PageObserver.kt

@@ -9,14 +9,57 @@ package com.drake.net.observer
 
 import android.view.View
 import android.view.View.OnAttachStateChangeListener
+import android.widget.Toast
 import com.drake.brv.PageRefreshLayout
+import com.drake.net.NetConfig
+import com.drake.net.R
+import com.drake.net.error.ParseJsonException
+import com.drake.net.error.RequestParamsException
+import com.drake.net.error.ResponseException
+import com.drake.net.error.ServerResponseException
+import com.yanzhenjie.kalle.exception.*
 import io.reactivex.observers.DefaultObserver
 
 /**
  * 自动结束下拉刷新和上拉加载状态
+ * 自动展示缺省页
+ * 自动分页加载
  */
 abstract class PageObserver<M>(val pageRefreshLayout: PageRefreshLayout) : DefaultObserver<M>() {
 
+    companion object {
+        internal var onPageError: Throwable.(pageRefreshLayout: PageRefreshLayout) -> Unit = {
+
+            val message = when (this) {
+                is NetworkError -> NetConfig.app.getString(R.string.network_error)
+                is URLError -> NetConfig.app.getString(R.string.url_error)
+                is HostError -> NetConfig.app.getString(R.string.host_error)
+                is ConnectTimeoutError -> NetConfig.app.getString(R.string.connect_timeout_error)
+                is ConnectException -> NetConfig.app.getString(R.string.connect_exception)
+                is WriteException -> NetConfig.app.getString(R.string.write_exception)
+                is ReadTimeoutError -> NetConfig.app.getString(R.string.read_timeout_error)
+                is DownloadError -> NetConfig.app.getString(R.string.download_error)
+                is NoCacheError -> NetConfig.app.getString(R.string.no_cache_error)
+                is ReadException -> NetConfig.app.getString(R.string.read_exception)
+                is ParseError -> NetConfig.app.getString(R.string.parse_error)
+                is ParseJsonException -> NetConfig.app.getString(R.string.parse_json_error)
+                is RequestParamsException -> NetConfig.app.getString(R.string.request_error)
+                is ServerResponseException -> NetConfig.app.getString(R.string.server_error)
+                is ResponseException -> msg
+                else -> {
+                    printStackTrace()
+                    NetConfig.app.getString(R.string.other_error)
+                }
+            }
+
+            when (this) {
+                is ParseError, is ParseJsonException, is ResponseException, is RequestParamsException, is ServerResponseException ->
+                    Toast.makeText(NetConfig.app, message, Toast.LENGTH_SHORT).show()
+            }
+
+        }
+    }
+
     init {
         pageRefreshLayout.addOnAttachStateChangeListener(object : OnAttachStateChangeListener {
             override fun onViewAttachedToWindow(v: View) {
@@ -35,11 +78,17 @@ abstract class PageObserver<M>(val pageRefreshLayout: PageRefreshLayout) : Defau
      * @param e 包括错误信息
      */
     override fun onError(e: Throwable) {
-        pageRefreshLayout.finish(false)
+        if (pageRefreshLayout.stateEnabled) {
+            pageRefreshLayout.showError()
+        } else pageRefreshLayout.finish(false)
+
+        onPageError.invoke(e, pageRefreshLayout)
     }
 
     override fun onComplete() {
-        pageRefreshLayout.finish(true)
+        if (pageRefreshLayout.stateEnabled) {
+            pageRefreshLayout.showContent()
+        } else pageRefreshLayout.finish(true)
     }
 
     /**

+ 12 - 6
net/src/main/java/com/drake/net/observer/RefreshObserver.kt

@@ -9,19 +9,22 @@ package com.drake.net.observer
 
 import android.view.View
 import android.view.View.OnAttachStateChangeListener
-import com.drake.brv.PageRefreshLayout
 import com.drake.net.NetConfig
+import com.scwang.smart.refresh.layout.SmartRefreshLayout
 import io.reactivex.observers.DefaultObserver
 
 /**
- * 自动结束下拉刷新和上拉加载状态
+ * 自动结束下拉刷新
  */
-abstract class RefreshObserver<M>(val pageRefreshLayout: PageRefreshLayout) :
+abstract class RefreshObserver<M>(
+    val refreshLayout: SmartRefreshLayout,
+    val loadMore: Boolean = false
+) :
     DefaultObserver<M>() {
 
 
     init {
-        pageRefreshLayout.addOnAttachStateChangeListener(object : OnAttachStateChangeListener {
+        refreshLayout.addOnAttachStateChangeListener(object : OnAttachStateChangeListener {
             override fun onViewAttachedToWindow(v: View) {
 
             }
@@ -31,6 +34,9 @@ abstract class RefreshObserver<M>(val pageRefreshLayout: PageRefreshLayout) :
         })
     }
 
+    override fun onStart() {
+        refreshLayout.setEnableLoadMore(loadMore)
+    }
 
     /**
      * 关闭进度对话框并提醒错误信息
@@ -38,12 +44,12 @@ abstract class RefreshObserver<M>(val pageRefreshLayout: PageRefreshLayout) :
      * @param e 包括错误信息
      */
     override fun onError(e: Throwable) {
-        pageRefreshLayout.finish(false)
+        refreshLayout.finishRefresh(false)
         NetConfig.onError.invoke(e)
     }
 
 
     override fun onComplete() {
-        pageRefreshLayout.finish(true)
+        refreshLayout.finishRefresh(true)
     }
 }

+ 1 - 4
net/src/main/res/values/strings.xml

@@ -14,13 +14,10 @@
     <string name="no_cache_error">读取缓存错误</string>
     <string name="parse_error">解析数据时发生异常</string>
     <string name="read_exception">读取数据错误</string>
-    <string name="other_error">服务器未响应</string>
-
-    <!--DefaultConverter-->
-    <string name="parse_data_error">解析数据错误</string>
     <string name="parse_json_error">解析JSON错误</string>
     <string name="request_error">请求参数错误</string>
     <string name="server_error">服务响应错误</string>
+    <string name="other_error">服务器未响应</string>
 
 
 </resources>

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

@@ -3,7 +3,6 @@ package com.drake.net.sample
 import android.app.Application
 import com.drake.net.convert.DefaultConverter
 import com.drake.net.initNet
-import com.drake.net.onError
 import com.squareup.moshi.Moshi
 import java.lang.reflect.Type
 
@@ -12,12 +11,7 @@ class App : Application() {
     override fun onCreate() {
         super.onCreate()
 
-        initNet("") {
-
-            onError {
-
-            }
-
+        initNet("http://localhost.com") {
             converter(object : DefaultConverter() {
                 override fun <S> convert(succeed: Type, body: String): S? {
                     return Moshi.Builder().build().adapter<S>(succeed).fromJson(body)