Quellcode durchsuchen

- Interval 轮循器增加重置功能

drake vor 5 Jahren
Ursprung
Commit
0c7b91c86d

+ 130 - 63
README.md

@@ -4,6 +4,10 @@
 
 
 
+Android 创新式的网络请求库, 完美扩展RxJava|列表|缺省页
+
+
+
 主要新增特性
 
 - Kotlin DSL
@@ -54,16 +58,96 @@ allprojects {
 module 的 build.gradle
 
 ```groovy
-implementation 'com.github.liangjingkanji:Net:1.3.0'
+implementation 'com.github.liangjingkanji:Net:1.3.1'
+```
+
+
+
+
+
+## 请求方式
+
+### Post
+
+```kotlin
+post<Model>(""){
+  param("key", "value")
+}.net { 
+
+}
+```
+
+`Model` 即JSONBean或者说POJO 数据模型, 会将服务器返回的JSON解析成该数据模型在`net`回调中可以使用`it`调用
+
+
+
+### Get
+
+```
+get<Model>(""){
+  param("key", "value")
+}.net { 
+
+}
+```
+
+`Model` 泛型如果换成String, 将会在成功回调中得到字符串对象.
+
+
+
+### 文件上传
+
+```kotlin
+post<Model>(""){
+  file("file", File("path"))
+}.net {
+
+}
 ```
 
+这是支持Kalle任何参数添加方式
 
 
 
+### 文件下载
 
+```kotlin
+download("/path", "下载目录"){
 
+  // 进度监听
+  onProgress { progress, byteCount, speed ->
+
+             }
+
+}.dialog(this){
+
+}
+```
 
-## 初始化和配置
+
+
+### 下载图片
+
+下载图片要求首先导入Glide依赖库, 下载图片和下载文件不同在于可以手动指定图片宽高
+
+```kotlin
+Context.downloadImg(url: String, with: Int = -1, height: Int = -1)
+```
+
+
+
+示例
+
+```kotlin
+val netObserver = downloadImg(
+  "https://cdn.sspai.com/article/ebe361e4-c891-3afd-8680-e4bad609723e.jpg?imageMogr2/quality/95/thumbnail/!2880x620r/gravity/Center/crop/2880x620/interlace/1".
+  200,200
+).net(this) {
+  it // File对象
+}
+```
+
+## 初始化
 
 ```kotlin
 class App : Application() {
@@ -73,7 +157,7 @@ class App : Application() {
 
         initNet("主机名"){
 
-            // 转换器, 也可以自己实现Convert或者复写DefaultConverter
+            // 转换器, 也可以自己实现Convert或者复写DefaultConverter.
             converter(object : DefaultConverter() {
                 override fun <S> convert(succeed: Type, body: String): S? {
 					// 解析Json, 我这里是用的Moshi, 你也可以使用Gson之类的解析框架
@@ -191,84 +275,35 @@ initNet("http://192.168.2.1") {
 
 
 
-## 请求方式
-
-Post
-
-```kotlin
-post<Model>(""){
-  param("key", "value")
-}.net { 
-
-}
-```
-
-`Model` 即JSONBean或者说POJO 数据模型, 会将服务器返回的JSON解析成该数据模型在`net`回调中可以使用`it`调用
-
-
-
-Get
-
-```
-get<Model>(""){
-  param("key", "value")
-}.net { 
-
-}
-```
-
-`Model` 泛型如果换成String, 将会在成功回调中得到字符串对象.
-
+## 
 
+## 生命周期
 
-文件上传
+将Fragment或者Activity作为参数传递即可在页面关闭时自动取消订阅, 避免操作已销毁视图.
 
 ```kotlin
 post<Model>(""){
-  file("file", File("path"))
-}.net {
+  param("key", "value")
+}.net(activity) { 
 
 }
 ```
 
-这是支持Kalle任何参数添加方式
-
+其他的对话框或者缺省页和下拉刷新等自动支持生命周期管理
 
 
-文件下载
 
-```kotlin
-download("/path", "下载目录"){
-
-  // 进度监听
-  onProgress { progress, byteCount, speed ->
+如果是`net`跟随生命周期
 
-             }
-
-}.dialog(this){
-
-}
 ```
-
-
-
-## 生命周期
-
-将Fragment或者Activity作为参数传递即可在页面关闭时自动取消订阅, 避免操作已销毁视图.
-
-```kotlin
 post<Model>(""){
   param("key", "value")
-}.net(activity) { 
+}.net(activity, Lifecycle.Event.ON_DESTROY) { 
 
 }
 ```
 
-其他的对话框或者缺省页和下拉刷新等自动支持生命周期管理
-
-Net框架本身的生命周期管理是针对Fragment|Activity的页面销毁时才会自动取消订阅, 如果需要自定义页面生命周期推荐使用我的另外一个库: [AutoDispose](https://github.com/liangjingkanji/AutoDispose)
-
-返回值 Disposable 可以用于完全手动任何位置取消, 
+返回值 Disposable 可以用于完全手动任何位置取消
 
 ## 对话框
 
@@ -440,6 +475,8 @@ val netObserver = download(
 
 
 
+本网络请求的所有的Observer都不仅仅是网络请求可以用, 可以配合任何其他的被观察者使用, 主要解决视图更新以及生命周期问题
+
 ## 请求和响应规范
 
 很多时候存在请求和响应的后台接口规范不是常规统一的, 这个时候我们可以自己拦截处理数据. 
@@ -494,7 +531,7 @@ abstract class DefaultConverter(
 
 ## 轮循器
 
-本框架附带一个轮循器`Interval`
+本框架附带一个超级强大的轮循器`Interval`, 基本上包含轮循器所需要到所有功能
 
 - 支持多个观察者订阅同一个计时器
 - 开始(即subscribe订阅) | 暂停 | 继续 | 停止
@@ -510,4 +547,34 @@ subscribe() // 即开启定时器, 订阅多个也会监听同一个计数器
 stop() // 结束
 pause() // 暂停
 resume() // 继续
-```
+reset // 重置轮循器(包含计数器count和计时period)
+```
+
+
+
+## 快速创建被观察者
+
+```
+from { }.auto(this).subscribe { 
+	
+}
+```
+
+这里提到`from`可以快速创建一个被观察者. 函数参数返回值即发送的事件
+
+`auto`函数可以跟随生命周期自动取消订阅
+
+
+
+快速切换线程
+
+```kotlin
+from { 
+  // 这里属于IO线程 
+  8
+}.io().observeMain.auto(this).subscribe { 
+  // 这里属于主线程
+  // 这里会受到 事件 8
+}
+```
+

+ 31 - 27
net/src/main/java/com/drake/net/Interval.kt

@@ -18,10 +18,11 @@ import java.util.concurrent.atomic.AtomicReference
 
 
 /**
- * 轮循器
+ * 非常强大的轮循器
  *
  * 多个观察者可观察同一个计时器
- * 开始 | 暂停 | 继续 | 结束
+ *
+ * 支持 开始 | 暂停 | 继续 | 结束 | 重置 | 中途修改计数器
  */
 class Interval(
     var end: Long, // -1 表示永远不结束, 可以修改
@@ -45,37 +46,37 @@ class Interval(
     private var observerList = ArrayList<IntervalRangeObserver>()
     private var pause = false
     private var stop = false
+    private lateinit var dispose: Disposable
+    private val iterator = {
 
+        if (!pause) {
+            synchronized(this) {
+                count += 1
+            }
+            for (i in 0 until observerList.size) {
+                observerList[i].run(count, end, stop)
+            }
+        }
+    }
 
     public override fun subscribeActual(observer: Observer<in Long?>) {
 
-        val agentObserver =
-            IntervalRangeObserver(observer)
-
+        val agentObserver = IntervalRangeObserver(observer)
         observerList.add(agentObserver)
+
         observer.onSubscribe(agentObserver)
 
-        if (observerList.size == 1) {
-            val sch = scheduler
-            val iterator = {
-
-                if (!pause) {
-                    synchronized(this) {
-                        count += 1
-                    }
-                    for (i in 0 until observerList.size) {
-                        observerList[i].run(count, end, stop)
-                    }
-                }
-            }
-            if (sch is TrampolineScheduler) {
-                val worker = sch.createWorker()
-                agentObserver.setResource(worker)
-                worker.schedulePeriodically(iterator, initialDelay, period, unit)
-            } else {
-                val d = sch.schedulePeriodicallyDirect(iterator, initialDelay, period, unit)
-                agentObserver.setResource(d)
-            }
+        if (!this::dispose.isInitialized) init()
+        agentObserver.setResource(dispose)
+    }
+
+    private fun init() {
+        dispose = if (scheduler is TrampolineScheduler) {
+            val worker = scheduler.createWorker()
+            worker.schedulePeriodically(iterator, initialDelay, period, unit)
+            worker
+        } else {
+            scheduler.schedulePeriodicallyDirect(iterator, initialDelay, period, unit)
         }
     }
 
@@ -97,9 +98,12 @@ class Interval(
 
     /**
      * 重置轮循器
+     * count = start , 计时器重置
      */
     fun reset() {
         count = start
+        dispose.dispose()
+        init()
     }
 
     /**
@@ -110,7 +114,7 @@ class Interval(
     }
 
     /**
-     * 继续轮循器
+     * 如果轮循器被暂停的情况下继续轮循器
      */
     fun resume() {
         pause = false

+ 45 - 1
net/src/main/java/com/drake/net/observer/ObservableUtils.kt

@@ -9,9 +9,13 @@ package com.drake.net.observer
 
 import android.os.Handler
 import android.os.Looper
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
+import androidx.lifecycle.LifecycleOwner
 import io.reactivex.Observable
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.schedulers.Schedulers
+import org.reactivestreams.Subscriber
 
 // <editor-fold desc="被观察者线程">
 
@@ -64,7 +68,9 @@ fun <M> Observable<M>.observeComputation(): Observable<M> {
 
 // </editor-fold>
 
-
+/**
+ * 在主线程运行
+ */
 fun runMain(block: () -> Unit) {
     if (Looper.myLooper() == Looper.getMainLooper()) {
         block()
@@ -74,10 +80,48 @@ fun runMain(block: () -> Unit) {
 }
 
 
+/**
+ * io线程 -> main线程
+ */
 fun <M> Observable<M>.async(): Observable<M> {
     return subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
 }
 
+// <editor-fold desc="创建被观察者">
+
+/**
+ * 快速创建一个被观察者
+ * @param M 返回值定义被观察者发射事件类型
+ */
 fun <M> from(block: () -> M): Observable<M> {
     return Observable.fromCallable(block)
+}
+
+fun <M> publish(block: (emitter: Subscriber<in M>) -> Unit): Observable<M> {
+    return Observable.fromPublisher(block)
+}
+
+// </editor-fold>
+
+
+/**
+ * 自动跟随生命周期取消观察者订阅
+ */
+fun <T> Observable<T>.auto(
+    lifecycleOwner: LifecycleOwner,
+    event: Lifecycle.Event = Lifecycle.Event.ON_DESTROY
+): Observable<T> {
+
+    return doOnLifecycle({ dispose ->
+
+        lifecycleOwner.lifecycle.addObserver(object : LifecycleEventObserver {
+
+            override fun onStateChanged(source: LifecycleOwner, actualEvent: Lifecycle.Event) {
+                if (event == actualEvent) {
+                    dispose.dispose()
+                }
+            }
+
+        })
+    }, {})
 }

+ 1 - 1
sample/build.gradle

@@ -39,7 +39,7 @@ dependencies {
 
     implementation 'com.squareup.moshi:moshi-kotlin:1.8.0'
     kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.8.0'
-    implementation 'com.github.liangjingkanji:BRV:1.1.4'
+    implementation 'com.github.liangjingkanji:BRV:1.1.6'
     implementation 'com.scwang.smart:refresh-header-classics:2.0.0-alpha-1'
     implementation 'com.scwang.smart:refresh-footer-classics:2.0.0-alpha-1'
     implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'

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

@@ -3,7 +3,6 @@ package com.drake.net.sample
 import android.os.Bundle
 import androidx.appcompat.app.AppCompatActivity
 import com.drake.net.download
-import com.drake.net.observer.net
 
 class MainActivity : AppCompatActivity() {
 
@@ -12,15 +11,10 @@ class MainActivity : AppCompatActivity() {
         setContentView(R.layout.activity_main)
 
 
-        val netObserver = download(
-            "https://cdn.sspai.com/article/ebe361e4-c891-3afd-8680-e4bad609723e.jpg?imageMogr2/quality/95/thumbnail/!2880x620r/gravity/Center/crop/2880x620/interlace/1",
-            isAbsolutePath = true
-        ).net(this) {
-        }.error {
-            handleError(it)
-        }
+        val download = download(
+            "https://cdn.sspai.com/article/ebe361e4-c891-3afd-8680-e4bad609723e.jpg?imageMogr2/quality/95/thumbnail/!2880x620r/gravity/Center/crop/2880x620/interlace/1"
+        )
+    }
 
-        netObserver.dispose() // 立刻取消
 
-    }
 }