Browse Source

sample: 新增限时请求/定时请求示例

drake 2 years ago
parent
commit
3899c76292

+ 56 - 0
docs/timing.md

@@ -0,0 +1,56 @@
+以下仅提供一些如何实现定时/限时请求功能的思路, 并不限定只有以下描述的方式可以实现
+
+
+## 限时请求
+
+```kotlin
+scopeDialog {
+    // 当接口请求在100毫秒内没有完成会抛出异常TimeoutCancellationException
+    withTimeout(100) {
+        Get<String>(Api.BANNER).await()
+    }
+}.catch {
+    Log.e("日志", "catch", it) // catch无法接收到CancellationException异常
+}.finally {
+    Log.e("日志", "finally", it) // TimeoutCancellationException属于CancellationException子类故只会被finally接收到
+    if (it is TimeoutCancellationException) {
+        toast("由于未在指定时间完成请求则取消请求")
+    }
+}
+```
+
+## 定时请求
+
+指定请求10次
+
+```kotlin
+scopeNetLife {
+    // 每两秒请求一次, 总共执行10次
+    repeat(20) {
+        delay(1000)
+        val data =
+            Get<String>("http://api.k780.com/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json").await()
+        binding.tvContent.text =
+            JSONObject(data).getJSONObject("result").getString("datetime_2")
+        // 通过return@repeat可以终止循环
+    }
+}
+```
+
+无限循环请求, 可以根据某个条件`break`退出
+
+```kotlin
+scopeNetLife {
+    // 每两秒请求一次, 总共执行10次
+    while (true) {
+        delay(1.toDuration(DurationUnit.SECONDS))
+        val data =
+            Get<String>("http://api.k780.com/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json").await()
+        binding.tvContent.text =
+            JSONObject(data).getJSONObject("result").getString("datetime_2")
+        // 通过break可以终止循环
+    }
+}
+```
+
+建议下载源码查看

+ 1 - 0
mkdocs.yml

@@ -74,6 +74,7 @@ nav:
   - 最快请求结果: fastest.md
   - 日志插件: log-recorder.md
   - 通知栏日志: log-notice.md
+  - 限时/定时请求: timing.md
   - Callback: callback.md
   - 轮询器/倒计时: interval.md
   - 社区讨论: https://github.com/liangjingkanji/Net/discussions

+ 26 - 0
net/src/main/res/drawable/ic_limited_time.xml

@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2018 Drake, https://github.com/liangjingkanji
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="M6,2l0.01,6L10,12l-3.99,4.01L6,22h12v-6l-4,-4l4,-3.99V2H6zM16,16.5V20H8v-3.5l4,-4L16,16.5z"
+      android:fillColor="#000000" />
+</vector>

+ 29 - 0
net/src/main/res/drawable/ic_timing.xml

@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright (C) 2018 Drake, https://github.com/liangjingkanji
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  ~
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <path
+        android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8z"
+        android:fillColor="#000000" />
+    <path
+        android:pathData="M12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"
+        android:fillColor="#000000" />
+</vector>

+ 54 - 0
sample/src/main/java/com/drake/net/sample/ui/fragment/LimitedTimeFragment.kt

@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 Drake, https://github.com/liangjingkanji
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.drake.net.sample.ui.fragment
+
+import android.util.Log
+import android.view.View
+import com.drake.engine.base.EngineFragment
+import com.drake.net.Get
+import com.drake.net.sample.R
+import com.drake.net.sample.constants.Api
+import com.drake.net.sample.databinding.FragmentLimitedTimeBinding
+import com.drake.net.utils.scopeDialog
+import com.drake.tooltip.toast
+import kotlinx.coroutines.TimeoutCancellationException
+import kotlinx.coroutines.withTimeout
+
+class LimitedTimeFragment : EngineFragment<FragmentLimitedTimeBinding>(R.layout.fragment_limited_time) {
+    override fun initView() {
+        binding.v = this
+    }
+
+    override fun initData() {
+    }
+
+    override fun onClick(v: View) {
+        scopeDialog {
+            // 当接口请求在100毫秒内没有完成会抛出异常TimeoutCancellationException
+            withTimeout(100) {
+                Get<String>(Api.BANNER).await()
+            }
+        }.catch {
+            Log.e("日志", "catch", it) // catch无法接收到CancellationException异常
+        }.finally {
+            Log.e("日志", "finally", it) // TimeoutCancellationException属于CancellationException子类故只会被finally接收到
+            if (it is TimeoutCancellationException) {
+                toast("由于未在指定时间完成请求则取消请求")
+            }
+        }
+    }
+}

+ 83 - 0
sample/src/main/java/com/drake/net/sample/ui/fragment/TimingRequestFragment.kt

@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2018 Drake, https://github.com/liangjingkanji
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.drake.net.sample.ui.fragment
+
+import android.view.View
+import com.drake.engine.base.EngineFragment
+import com.drake.net.Get
+import com.drake.net.sample.R
+import com.drake.net.sample.databinding.FragmentTimingRequestBinding
+import com.drake.net.utils.scopeNetLife
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.delay
+import org.json.JSONObject
+import kotlin.time.DurationUnit
+import kotlin.time.toDuration
+
+class TimingRequestFragment : EngineFragment<FragmentTimingRequestBinding>(R.layout.fragment_timing_request) {
+
+    private var scope: CoroutineScope? = null
+
+    override fun initView() {
+        binding.v = this
+    }
+
+    override fun initData() {
+    }
+
+    override fun onClick(v: View) {
+        when (v) {
+            binding.btnRepeat -> repeatRequest()
+            binding.infinityRepeat -> infinityRequest()
+            binding.btnCancel -> scope?.cancel()
+        }
+    }
+
+    /** 重复请求10次 */
+    private fun repeatRequest() {
+        scope?.cancel()
+        scope = scopeNetLife {
+            // 每两秒请求一次, 总共执行10次
+            repeat(20) {
+                delay(1000)
+                val data =
+                    Get<String>("http://api.k780.com/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json").await()
+                binding.tvContent.text =
+                    JSONObject(data).getJSONObject("result").getString("datetime_2")
+                // 通过return@repeat可以终止循环
+            }
+        }
+    }
+
+    /** 无限次数请求 */
+    private fun infinityRequest() {
+        scope?.cancel()
+        scope = scopeNetLife {
+            // 每两秒请求一次, 总共执行10次
+            while (true) {
+                delay(1.toDuration(DurationUnit.SECONDS))
+                val data =
+                    Get<String>("http://api.k780.com/?app=life.time&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json").await()
+                binding.tvContent.text =
+                    JSONObject(data).getJSONObject("result").getString("datetime_2")
+                // 通过break可以终止循环
+            }
+        }
+    }
+
+}

+ 41 - 0
sample/src/main/res/layout/fragment_limited_time.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2018 Drake, https://github.com/liangjingkanji
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <data>
+
+        <variable
+            name="v"
+            type="com.drake.net.sample.ui.fragment.LimitedTimeFragment" />
+
+    </data>
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        tools:context=".ui.fragment.LimitedTimeFragment">
+
+        <Button
+            click="@{v}"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:text="开始请求" />
+
+    </FrameLayout>
+</layout>

+ 65 - 0
sample/src/main/res/layout/fragment_timing_request.xml

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2018 Drake, https://github.com/liangjingkanji
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<layout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <data>
+
+        <variable
+            name="v"
+            type="com.drake.net.sample.ui.fragment.TimingRequestFragment" />
+
+    </data>
+
+    <androidx.appcompat.widget.LinearLayoutCompat
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:orientation="vertical"
+        tools:context=".ui.fragment.LimitedTimeFragment">
+
+        <TextView
+            android:id="@+id/tvContent"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="50dp"
+            android:text="Waiting..." />
+
+        <Button
+            android:id="@+id/btnRepeat"
+            click="@{v}"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="请求指定次数" />
+
+        <Button
+            android:id="@+id/infinityRepeat"
+            click="@{v}"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="无限循环请求" />
+
+        <Button
+            android:id="@+id/btnCancel"
+            click="@{v}"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="30dp"
+            android:text="取消请求" />
+
+    </androidx.appcompat.widget.LinearLayoutCompat>
+</layout>

+ 8 - 0
sample/src/main/res/menu/menu_main.xml

@@ -115,4 +115,12 @@
         android:id="@+id/request_callback"
         android:icon="@drawable/ic_callback_request"
         android:title="Callback" />
+    <item
+        android:id="@+id/limitedTimeFragment"
+        android:icon="@drawable/ic_limited_time"
+        android:title="限时请求" />
+    <item
+        android:id="@+id/timingRequestFragment"
+        android:icon="@drawable/ic_timing"
+        android:title="定时请求" />
 </menu>

+ 8 - 0
sample/src/main/res/navigation/nav_main.xml

@@ -140,5 +140,13 @@
         android:id="@+id/previewCacheFragment"
         android:name="com.drake.net.sample.ui.fragment.PreviewCacheFragment"
         android:label="PreviewCacheFragment" />
+    <fragment
+        android:id="@+id/limitedTimeFragment"
+        android:name="com.drake.net.sample.ui.fragment.LimitedTimeFragment"
+        android:label="限时请求" />
+    <fragment
+        android:id="@+id/timingRequestFragment"
+        android:name="com.drake.net.sample.ui.fragment.TimingRequestFragment"
+        android:label="定时请求" />
 
 </navigation>