瀏覽代碼

+ Observable.interval可以获取事件之间时间间隔, 初次间隔-1
| 异常提示遗漏

drake 5 年之前
父節點
當前提交
55b73ae17b

+ 34 - 1
README.md

@@ -58,7 +58,7 @@ allprojects {
 module 的 build.gradle
 module 的 build.gradle
 
 
 ```groovy
 ```groovy
-implementation 'com.github.liangjingkanji:Net:1.3.3'
+implementation 'com.github.liangjingkanji:Net:1.3.4'
 ```
 ```
 
 
 
 
@@ -552,6 +552,39 @@ reset // 重置轮循器(包含计数器count和计时period)
 
 
 
 
 
 
+### 事件间隔
+
+修复官方timInterval初始事件依然存在时间间隔问题
+
+```
+Observabl.interval
+```
+
+示例: 返回两次退出应用
+
+```kotlin
+class MainActivity : AppCompatActivity() {
+
+    val exit = PublishSubject.create<Boolean>()
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_main)
+
+        exit.interval(TimeUnit.MILLISECONDS).observeMain().subscribe {
+            if (it.time() >= 2 || it.time() == -1L) Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show() 
+            else super.onBackPressed()
+        }
+    }
+
+    override fun onBackPressed() {
+        exit.onNext(true)
+    }
+}
+```
+
+
+
 ## 快速创建被观察者
 ## 快速创建被观察者
 
 
 使用本框架定义的创建被观察者函数可以避免异步阻塞时发射事件导致的空指针
 使用本框架定义的创建被观察者函数可以避免异步阻塞时发射事件导致的空指针

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

@@ -10,8 +10,6 @@ package com.drake.net
 import android.app.Application
 import android.app.Application
 import android.app.Dialog
 import android.app.Dialog
 import android.content.Context
 import android.content.Context
-import android.os.Handler
-import android.os.Looper
 import android.view.View
 import android.view.View
 import android.widget.Toast
 import android.widget.Toast
 import androidx.fragment.app.FragmentActivity
 import androidx.fragment.app.FragmentActivity
@@ -19,6 +17,7 @@ import com.drake.net.error.RequestParamsException
 import com.drake.net.error.ResponseException
 import com.drake.net.error.ResponseException
 import com.drake.net.error.ServerResponseException
 import com.drake.net.error.ServerResponseException
 import com.drake.net.observer.DialogObserver
 import com.drake.net.observer.DialogObserver
+import com.drake.net.observer.runMain
 import com.yanzhenjie.kalle.Kalle
 import com.yanzhenjie.kalle.Kalle
 import com.yanzhenjie.kalle.KalleConfig
 import com.yanzhenjie.kalle.KalleConfig
 import com.yanzhenjie.kalle.exception.*
 import com.yanzhenjie.kalle.exception.*
@@ -31,7 +30,7 @@ object NetConfig {
     lateinit var app: Application
     lateinit var app: Application
 
 
     internal var defaultToast: Toast? = null
     internal var defaultToast: Toast? = null
-    internal var defaultDialog: (DialogObserver<*>.(context: FragmentActivity) -> Dialog)? = null
+    internal var defaultDialog: (DialogObserver<*>.(FragmentActivity) -> Dialog)? = null
     internal var onError: Throwable.() -> Unit = {
     internal var onError: Throwable.() -> Unit = {
 
 
         val message = when (this) {
         val message = when (this) {
@@ -76,13 +75,14 @@ object NetConfig {
             is RequestParamsException -> app.getString(R.string.net_request_error)
             is RequestParamsException -> app.getString(R.string.net_request_error)
             is ServerResponseException -> app.getString(R.string.net_server_error)
             is ServerResponseException -> app.getString(R.string.net_server_error)
             is ExecutionException -> app.getString(R.string.net_image_error)
             is ExecutionException -> app.getString(R.string.net_image_error)
+            is NullPointerException -> app.getString(R.string.net_null_error)
             is ResponseException -> msg
             is ResponseException -> msg
             else -> app.getString(R.string.net_other_error)
             else -> app.getString(R.string.net_other_error)
         }
         }
 
 
         printStackTrace()
         printStackTrace()
         when (this) {
         when (this) {
-            is ParseError, is ResponseException -> app.toast(message)
+            is ParseError, is ResponseException, is NullPointerException -> app.toast(message)
         }
         }
     }
     }
 }
 }
@@ -152,12 +152,4 @@ internal fun Context.toast(message: CharSequence, config: Toast.() -> Unit = {})
     }
     }
 }
 }
 
 
-private fun runMain(block: () -> Unit) {
-    if (Looper.myLooper() == Looper.getMainLooper()) {
-        block()
-    } else {
-        Handler(Looper.getMainLooper()).post { block() }
-    }
-}
-
 
 

+ 87 - 0
net/src/main/java/com/drake/net/observable/TimeInterval.kt

@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018, Umbrella CompanyLimited All rights reserved.
+ * Project:Net
+ * Author:Drake
+ * Date:12/7/19 7:08 PM
+ */
+package com.drake.net.observable
+
+import io.reactivex.Observable
+import io.reactivex.ObservableSource
+import io.reactivex.Observer
+import io.reactivex.Scheduler
+import io.reactivex.disposables.Disposable
+import io.reactivex.internal.disposables.DisposableHelper
+import io.reactivex.schedulers.Schedulers
+import io.reactivex.schedulers.Timed
+import java.util.concurrent.TimeUnit
+
+/**
+ * 第一次事件的时间间隔[Timed.time]为 -1
+ */
+fun <T> Observable<T>.interval(
+    unit: TimeUnit,
+    scheduler: Scheduler = Schedulers.computation()
+): TimeInterval<T> {
+    return TimeInterval(this, unit, scheduler)
+}
+
+class TimeInterval<T>(
+    private val source: ObservableSource<T>,
+    private val unit: TimeUnit,
+    private val scheduler: Scheduler
+) : Observable<Timed<T>>() {
+
+    override fun subscribeActual(observer: Observer<in Timed<T>>) {
+        val timeIntervalObserver = TimeIntervalObserver(observer, unit, scheduler)
+        source.subscribe(timeIntervalObserver)
+    }
+
+    internal class TimeIntervalObserver<T>(
+        private val downstream: Observer<in Timed<T>>,
+        private val unit: TimeUnit,
+        private val scheduler: Scheduler
+    ) : Observer<T>, Disposable {
+
+        private var lastTime = 0L
+        private var first = true
+        private var upstream: Disposable? = null
+
+        override fun onSubscribe(d: Disposable) {
+            if (DisposableHelper.validate(upstream, d)) {
+                upstream = d
+
+                downstream.onSubscribe(this)
+            }
+        }
+
+        override fun dispose() {
+            upstream!!.dispose()
+        }
+
+        override fun isDisposed(): Boolean {
+            return upstream!!.isDisposed
+        }
+
+        override fun onNext(t: T) {
+            val now = scheduler.now(unit)
+
+            val delta = if (first) {
+                first = false; -1
+            } else now - lastTime
+
+            downstream.onNext(Timed(t, delta, unit))
+            lastTime = now
+        }
+
+        override fun onError(t: Throwable) {
+            downstream.onError(t)
+        }
+
+        override fun onComplete() {
+            downstream.onComplete()
+        }
+
+    }
+
+}

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

@@ -5,9 +5,12 @@ import androidx.appcompat.app.AppCompatActivity
 
 
 class MainActivity : AppCompatActivity() {
 class MainActivity : AppCompatActivity() {
 
 
+
     override fun onCreate(savedInstanceState: Bundle?) {
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         super.onCreate(savedInstanceState)
         setContentView(R.layout.activity_main)
         setContentView(R.layout.activity_main)
+
+
     }
     }
 
 
 }
 }