Jelajahi Sumber

sample: use mock data

drake 2 tahun lalu
induk
melakukan
bc35ea5302
36 mengubah file dengan 368 tambahan dan 158 penghapusan
  1. 1 0
      sample/build.gradle
  2. 3 0
      sample/src/main/java/com/drake/net/sample/base/App.kt
  3. 5 6
      sample/src/main/java/com/drake/net/sample/constants/Api.kt
  4. 6 1
      sample/src/main/java/com/drake/net/sample/converter/FastJsonConverter.kt
  5. 6 1
      sample/src/main/java/com/drake/net/sample/converter/GsonConverter.kt
  6. 4 3
      sample/src/main/java/com/drake/net/sample/converter/MoshiConverter.kt
  7. 62 0
      sample/src/main/java/com/drake/net/sample/mock/MockDispatcher.kt
  8. 0 14
      sample/src/main/java/com/drake/net/sample/model/CommonWebsite.kt
  9. 21 0
      sample/src/main/java/com/drake/net/sample/model/GameModel.kt
  10. 0 59
      sample/src/main/java/com/drake/net/sample/model/HomeArticleModel.kt
  11. 0 15
      sample/src/main/java/com/drake/net/sample/model/HomeBannerModel.kt
  12. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/AutoDialogFragment.kt
  13. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/CallbackRequestFragment.kt
  14. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/FastestFragment.kt
  15. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/InterceptorFragment.kt
  16. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/LimitedTimeFragment.kt
  17. 3 3
      sample/src/main/java/com/drake/net/sample/ui/fragment/ParallelNetworkFragment.kt
  18. 2 2
      sample/src/main/java/com/drake/net/sample/ui/fragment/PreviewCacheFragment.kt
  19. 5 5
      sample/src/main/java/com/drake/net/sample/ui/fragment/PullRefreshFragment.kt
  20. 3 3
      sample/src/main/java/com/drake/net/sample/ui/fragment/PushRefreshFragment.kt
  21. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/ReadCacheFragment.kt
  22. 9 9
      sample/src/main/java/com/drake/net/sample/ui/fragment/RequestMethodFragment.kt
  23. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/StateLayoutFragment.kt
  24. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/SyncRequestFragment.kt
  25. 1 1
      sample/src/main/java/com/drake/net/sample/ui/fragment/UniqueRequestFragment.kt
  26. 2 2
      sample/src/main/java/com/drake/net/sample/ui/fragment/UploadFileFragment.kt
  27. 3 3
      sample/src/main/java/com/drake/net/sample/ui/fragment/converter/FastJsonConvertFragment.kt
  28. 3 3
      sample/src/main/java/com/drake/net/sample/ui/fragment/converter/GsonConvertFragment.kt
  29. 3 3
      sample/src/main/java/com/drake/net/sample/ui/fragment/converter/MoshiConvertFragment.kt
  30. 3 3
      sample/src/main/java/com/drake/net/sample/ui/fragment/converter/SerializationConvertFragment.kt
  31. 3 3
      sample/src/main/java/com/drake/net/sample/vm/UserViewModel.kt
  32. 20 0
      sample/src/main/res/drawable/bg_input.xml
  33. 16 8
      sample/src/main/res/layout/fragment_view_model_request.xml
  34. 1 1
      sample/src/main/res/layout/item_list.xml
  35. 2 2
      sample/src/main/res/layout/item_pull_list.xml
  36. 173 0
      sample/src/main/res/raw/game.json

+ 1 - 0
sample/build.gradle

@@ -103,4 +103,5 @@ dependencies {
     implementation 'com.github.liangjingkanji:debugkit:1.3.0' // 开发调试窗口工具
     implementation "com.github.liangjingkanji:Tooltip:1.2.2" // 吐司工具
     implementation 'com.github.liangjingkanji:Engine:0.0.67'
+    implementation "com.squareup.okhttp3:mockwebserver:4.10.0"
 }

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

@@ -33,6 +33,7 @@ import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.converter.SerializationConverter
 import com.drake.net.sample.interfaces.MyRequestInterceptor
+import com.drake.net.sample.mock.MockDispatcher
 import com.drake.statelayout.StateConfig
 import com.drake.tooltip.dialog.BubbleDialog
 import com.scwang.smart.refresh.footer.ClassicsFooter
@@ -89,6 +90,8 @@ class App : Application() {
             }
         }
 
+        MockDispatcher.initialize()
+
         initializeThirdPart()
     }
 

+ 5 - 6
sample/src/main/java/com/drake/net/sample/constants/Api.kt

@@ -1,11 +1,10 @@
 package com.drake.net.sample.constants
 
 object Api {
-    const val HOST = "https://www.wanandroid.com/"
+    const val HOST = "http://127.0.0.1:8090"
 
-    const val BANNER = "banner/json"
-    const val LOGIN = "user/login"
-    const val UPLOAD = "upload"
-    const val FRIEND = "friend/json"
-    const val ARTICLE = "article/list/%s/json" // %s为分页索引
+    const val TEST = "/test"
+    const val DELAY = "/delay"
+    const val UPLOAD = "/upload"
+    const val GAME = "/game"
 }

+ 6 - 1
sample/src/main/java/com/drake/net/sample/converter/FastJsonConverter.kt

@@ -24,6 +24,11 @@ import java.lang.reflect.Type
 class FastJsonConverter : JSONConvert(code = "errorCode", message = "errorMsg", success = "0") {
 
     override fun <R> String.parseBody(succeed: Type): R? {
-        return JSON.parseObject(JSONObject(this).getString("data"), succeed)
+        val string = try {
+            JSONObject(this).getString("data")
+        } catch (e: Exception) {
+            this
+        }
+        return JSON.parseObject(string, succeed)
     }
 }

+ 6 - 1
sample/src/main/java/com/drake/net/sample/converter/GsonConverter.kt

@@ -27,6 +27,11 @@ class GsonConverter : JSONConvert(code = "errorCode", message = "errorMsg") {
     }
 
     override fun <R> String.parseBody(succeed: Type): R? {
-        return gson.fromJson<R>(JSONObject(this).getString("data"), succeed)
+        val string = try {
+            JSONObject(this).getString("data")
+        } catch (e: Exception) {
+            this
+        }
+        return gson.fromJson<R>(string, succeed)
     }
 }

+ 4 - 3
sample/src/main/java/com/drake/net/sample/converter/MoshiConverter.kt

@@ -29,10 +29,11 @@ class MoshiConverter : JSONConvert(code = "errorCode", message = "errorMsg", suc
     }
 
     override fun <R> String.parseBody(succeed: Type): R? {
-        return try {
-            moshi.adapter<R>(succeed).fromJson(JSONObject(this).getString("data"))
+        val string = try {
+            JSONObject(this).getString("data")
         } catch (e: Exception) {
-            moshi.adapter<R>(succeed).fromJson(this)
+            this
         }
+        return moshi.adapter<R>(succeed).fromJson(string)
     }
 }

+ 62 - 0
sample/src/main/java/com/drake/net/sample/mock/MockDispatcher.kt

@@ -0,0 +1,62 @@
+/*
+ * 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.mock
+
+import android.util.Log
+import com.drake.engine.base.app
+import com.drake.net.sample.R
+import com.drake.net.sample.constants.Api
+import okhttp3.mockwebserver.Dispatcher
+import okhttp3.mockwebserver.MockResponse
+import okhttp3.mockwebserver.MockWebServer
+import okhttp3.mockwebserver.RecordedRequest
+import okio.buffer
+import okio.source
+import java.util.concurrent.TimeUnit
+import kotlin.concurrent.thread
+
+class MockDispatcher : Dispatcher() {
+
+    companion object {
+        fun initialize() {
+            val srv = MockWebServer()
+            srv.dispatcher = MockDispatcher()
+            thread {
+                try {
+                    srv.start(8090)
+                } catch (e: Exception) {
+                    Log.e("日志", "MOCK服务启动失败", e)
+                }
+            }
+        }
+    }
+
+    override fun dispatch(request: RecordedRequest): MockResponse {
+        val response = MockResponse().setHeader("Content-Type", "application/json; charset=utf-8")
+
+        return when (request.path) {
+            Api.TEST -> response.setBody("Request Success : ${request.method}")
+            Api.DELAY -> response.setBodyDelay(2, TimeUnit.SECONDS).setBody("Request Success : ${request.method}")
+            Api.UPLOAD -> response.setBodyDelay(1, TimeUnit.SECONDS).setBody("Upload Success")
+            Api.GAME -> {
+                val buf = app.resources.openRawResource(R.raw.game).source().buffer().readUtf8()
+                response.setBodyDelay(1, TimeUnit.SECONDS).setBody(buf)
+            }
+            else -> response.setResponseCode(404)
+        }
+    }
+}

+ 0 - 14
sample/src/main/java/com/drake/net/sample/model/CommonWebsite.kt

@@ -1,14 +0,0 @@
-package com.drake.net.sample.model
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class CommonWebsite(
-    var category: String = "",
-    var icon: String = "",
-    var id: Int = 0,
-    var link: String = "",
-    var name: String = "",
-    var order: Int = 0,
-    var visible: Int = 0
-)

+ 21 - 0
sample/src/main/java/com/drake/net/sample/model/GameModel.kt

@@ -0,0 +1,21 @@
+package com.drake.net.sample.model
+
+@kotlinx.serialization.Serializable
+data class GameModel(
+    var total: Int = 0,
+    var list: List<Data> = listOf()
+) {
+
+    @kotlinx.serialization.Serializable
+    data class Data(
+        var id: Int = 0,
+        var img: String = "",
+        var name: String = "",
+        var label: List<String> = listOf(),
+        var price: String = "",
+        var initialPrice: String = "",
+        var grade: Int = 0,
+        var discount: Double = 0.0,
+        var endTime: Int = 0
+    )
+}

+ 0 - 59
sample/src/main/java/com/drake/net/sample/model/HomeArticleModel.kt

@@ -1,59 +0,0 @@
-package com.drake.net.sample.model
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class HomeArticleModel(
-    var curPage: Int = 0,
-    var datas: List<Data> = listOf(),
-    var offset: Int = 0,
-    var over: Boolean = false,
-    var pageCount: Int = 0,
-    var size: Int = 0,
-    var total: Int = 0
-) {
-
-    @Serializable
-    data class Data(
-        var apkLink: String = "",
-        var audit: Int = 0,
-        var author: String = "",
-        var canEdit: Boolean = false,
-        var chapterId: Int = 0,
-        var chapterName: String = "",
-        var collect: Boolean = false,
-        var courseId: Int = 0,
-        var desc: String = "",
-        var descMd: String = "",
-        var envelopePic: String = "",
-        var fresh: Boolean = false,
-        var host: String = "",
-        var id: Int = 0,
-        var link: String = "",
-        var niceDate: String = "",
-        var niceShareDate: String = "",
-        var origin: String = "",
-        var prefix: String = "",
-        var projectLink: String = "",
-        var publishTime: Long = 0,
-        var realSuperChapterId: Int = 0,
-        var selfVisible: Int = 0,
-        var shareDate: Long = 0,
-        var shareUser: String = "",
-        var superChapterId: Int = 0,
-        var superChapterName: String = "",
-        var tags: List<Tag> = listOf(),
-        var title: String = "",
-        var type: Int = 0,
-        var userId: Int = 0,
-        var visible: Int = 0,
-        var zan: Int = 0
-    ) {
-
-        @Serializable
-        data class Tag(
-            var name: String = "",
-            var url: String = ""
-        )
-    }
-}

+ 0 - 15
sample/src/main/java/com/drake/net/sample/model/HomeBannerModel.kt

@@ -1,15 +0,0 @@
-package com.drake.net.sample.model
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class HomeBannerModel(
-    var desc: String = "",
-    var id: Int = 0,
-    var imagePath: String = "",
-    var isVisible: Int = 0,
-    var order: Int = 0,
-    var title: String = "",
-    var type: Int = 0,
-    var url: String = ""
-)

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/AutoDialogFragment.kt

@@ -31,7 +31,7 @@ class AutoDialogFragment :
 
     override fun initView() {
         scopeDialog {
-            binding.tvFragment.text = Post<String>(Api.LOGIN) {
+            binding.tvFragment.text = Post<String>(Api.DELAY) {
                 param("username", "你的账号")
                 param("password", "123456")
             }.await()

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/CallbackRequestFragment.kt

@@ -19,7 +19,7 @@ class CallbackRequestFragment :
 
     override fun initView() {
         // Net同样支持OkHttp原始的队列任务
-        Net.post(Api.BANNER).enqueue(object : Callback {
+        Net.post(Api.TEST).enqueue(object : Callback {
             override fun onFailure(call: Call, e: IOException) {
             }
 

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/FastestFragment.kt

@@ -35,7 +35,7 @@ class FastestFragment : EngineFragment<FragmentFastestBinding>(R.layout.fragment
             */
 
             // 同时发起四个网络请求
-            val deferred2 = Get<String>(Api.BANNER) { setGroup("最快") }
+            val deferred2 = Get<String>(Api.TEST) { setGroup("最快") }
             val deferred3 = Post<String>("navi/json") { setGroup("最快") }
             val deferred = Get<String>("api0") { setGroup("最快") } // 错误接口
             val deferred1 = Get<String>("api1") { setGroup("最快") } // 错误接口

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/InterceptorFragment.kt

@@ -29,7 +29,7 @@ class InterceptorFragment :
 
     override fun initView() {
         scopeNetLife {
-            binding.tvFragment.text = Get<String>(Api.BANNER) {
+            binding.tvFragment.text = Get<String>(Api.TEST) {
                 // 拦截器只支持全局, 无法单例, 请查看[com.drake.net.sample.interceptor.NetInterceptor]
             }.await()
         }

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

@@ -40,7 +40,7 @@ class LimitedTimeFragment : EngineFragment<FragmentLimitedTimeBinding>(R.layout.
         scopeDialog {
             // 当接口请求在100毫秒内没有完成会抛出异常TimeoutCancellationException
             withTimeout(100) {
-                Get<String>(Api.BANNER).await()
+                Get<String>(Api.TEST).await()
             }
         }.catch {
             Log.e("日志", "catch", it) // catch无法接收到CancellationException异常

+ 3 - 3
sample/src/main/java/com/drake/net/sample/ui/fragment/ParallelNetworkFragment.kt

@@ -33,9 +33,9 @@ class ParallelNetworkFragment :
         scopeNetLife {
 
             // 同时发起三个请求
-            val deferred = Get<String>(Api.BANNER)
-            val deferred1 = Post<String>(Api.BANNER)
-            val deferred2 = Trace<String>(Api.BANNER)
+            val deferred = Get<String>(Api.TEST)
+            val deferred1 = Post<String>(Api.TEST)
+            val deferred2 = Trace<String>(Api.TEST)
 
             // 同时接收三个请求数据
             deferred.await()

+ 2 - 2
sample/src/main/java/com/drake/net/sample/ui/fragment/PreviewCacheFragment.kt

@@ -35,13 +35,13 @@ class PreviewCacheFragment : EngineFragment<FragmentReadCacheBinding>(R.layout.f
 
         scopeNetLife {
             // 然后执行这里(网络请求)
-            binding.tvFragment.text = Get<String>(Api.BANNER) {
+            binding.tvFragment.text = Get<String>(Api.TEST) {
                 setCacheMode(CacheMode.WRITE)
             }.await()
             Log.d("日志", "网络请求")
         }.preview(true) {
             // 先执行这里(仅读缓存), 任何异常都视为读取缓存失败
-            binding.tvFragment.text = Get<String>(Api.BANNER) {
+            binding.tvFragment.text = Get<String>(Api.TEST) {
                 setCacheMode(CacheMode.READ)
             }.await()
             Log.d("日志", "读取缓存")

+ 5 - 5
sample/src/main/java/com/drake/net/sample/ui/fragment/PullRefreshFragment.kt

@@ -23,7 +23,7 @@ import com.drake.net.Get
 import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.databinding.FragmentPullRefreshBinding
-import com.drake.net.sample.model.HomeArticleModel
+import com.drake.net.sample.model.GameModel
 import com.drake.net.utils.scope
 
 
@@ -32,14 +32,14 @@ class PullRefreshFragment :
 
     override fun initView() {
         binding.rv.linear().setup {
-            addType<HomeArticleModel.Data>(R.layout.item_pull_list)
+            addType<GameModel.Data>(R.layout.item_pull_list)
         }
 
         binding.page.onRefresh {
             scope {
-                val response = Get<HomeArticleModel>(String.format(Api.ARTICLE, index)).await()
-                addData(response.datas) {
-                    index < response.pageCount
+                val response = Get<GameModel>(String.format(Api.GAME, index)).await()
+                addData(response.list) {
+                    index < response.total
                 }
             }
         }.autoRefresh()

+ 3 - 3
sample/src/main/java/com/drake/net/sample/ui/fragment/PushRefreshFragment.kt

@@ -24,7 +24,7 @@ import com.drake.net.Get
 import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.databinding.FragmentPushRefreshBinding
-import com.drake.net.sample.model.CommonWebsite
+import com.drake.net.sample.model.GameModel
 import com.drake.net.utils.scope
 
 /** 本页面已禁用上拉加载(添加xml属性app:srlEnableLoadMore="false"), 只允许下拉刷新 */
@@ -33,12 +33,12 @@ class PushRefreshFragment :
 
     override fun initView() {
         binding.rv.linear().setup {
-            addType<CommonWebsite>(R.layout.item_list)
+            addType<GameModel.Data>(R.layout.item_list)
         }
 
         binding.page.onRefresh {
             scope {
-                binding.rv.models = Get<List<CommonWebsite>>(Api.FRIEND).await()
+                binding.rv.models = Get<GameModel>(Api.GAME).await().list
             }
         }.autoRefresh()
     }

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/ReadCacheFragment.kt

@@ -35,7 +35,7 @@ class ReadCacheFragment : EngineFragment<FragmentReadCacheBinding>(R.layout.frag
     override fun initView() {
         scopeNetLife {
             binding.tvFragment.text =
-                Post<String>(Api.BANNER) {
+                Post<String>(Api.TEST) {
                     setCacheMode(CacheMode.REQUEST_THEN_READ) // 请求网络失败会读取缓存, 请断网测试
                     // setCacheKey("自定义缓存KEY")
                 }.await()

+ 9 - 9
sample/src/main/java/com/drake/net/sample/ui/fragment/RequestMethodFragment.kt

@@ -41,49 +41,49 @@ class RequestMethodFragment :
 
     private fun GET() {
         scopeNetLife {
-            binding.tvFragment.text = Get<String>(Api.BANNER).await()
+            binding.tvFragment.text = Get<String>(Api.TEST).await()
         }
     }
 
     private fun POST() {
         scopeNetLife {
-            binding.tvFragment.text = Post<String>(Api.BANNER).await()
+            binding.tvFragment.text = Post<String>(Api.TEST).await()
         }
     }
 
     private fun HEAD() {
         scopeNetLife {
-            binding.tvFragment.text = Head<String>(Api.BANNER).await()
+            binding.tvFragment.text = Head<String>(Api.TEST).await()
         }
     }
 
     private fun PUT() {
         scopeNetLife {
-            binding.tvFragment.text = Put<String>(Api.BANNER).await()
+            binding.tvFragment.text = Put<String>(Api.TEST).await()
         }
     }
 
     private fun PATCH() {
         scopeNetLife {
-            binding.tvFragment.text = Patch<String>(Api.BANNER).await()
+            binding.tvFragment.text = Patch<String>(Api.TEST).await()
         }
     }
 
     private fun DELETE() {
         scopeNetLife {
-            binding.tvFragment.text = Delete<String>(Api.BANNER).await()
+            binding.tvFragment.text = Delete<String>(Api.TEST).await()
         }
     }
 
     private fun TRACE() {
         scopeNetLife {
-            binding.tvFragment.text = Trace<String>(Api.BANNER).await()
+            binding.tvFragment.text = Trace<String>(Api.TEST).await()
         }
     }
 
     private fun OPTIONS() {
         scopeNetLife {
-            binding.tvFragment.text = Options<String>(Api.BANNER).await()
+            binding.tvFragment.text = Options<String>(Api.TEST).await()
         }
     }
 
@@ -108,7 +108,7 @@ class RequestMethodFragment :
             // }.await()
 
             // 创建JSON
-            binding.tvFragment.text = Post<String>(Api.BANNER) {
+            binding.tvFragment.text = Post<String>(Api.TEST) {
                 json("name" to name, "age" to age, "measurements" to measurements) // 同时支持Map集合
             }.await()
         }

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/StateLayoutFragment.kt

@@ -33,7 +33,7 @@ class StateLayoutFragment :
     override fun initView() {
         binding.state.onRefresh {
             scope {
-                binding.tvFragment.text = Get<String>(Api.BANNER).await()
+                binding.tvFragment.text = Get<String>(Api.TEST).await()
             }
         }.showLoading()
     }

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/SyncRequestFragment.kt

@@ -13,7 +13,7 @@ class SyncRequestFragment :
     override fun initView() {
         thread { // 网络请求不允许在主线程
             val result = try {
-                Net.post(Api.BANNER).execute<String>()
+                Net.post(Api.TEST).execute<String>()
             } catch (e: Exception) { // 同步请求失败会导致崩溃要求捕获异常
                 "请求错误 = ${e.message}"
             }

+ 1 - 1
sample/src/main/java/com/drake/net/sample/ui/fragment/UniqueRequestFragment.kt

@@ -20,7 +20,7 @@ class UniqueRequestFragment :
             scope?.cancel() // 如果存在则取消
 
             scope = scopeNetLife {
-                val result = Post<String>(Api.BANNER).await()
+                val result = Post<String>(Api.TEST).await()
                 Log.d("日志", "请求到结果") // 你一直重复点击"发起请求"按钮会发现永远无法拿到请求结果, 因为每次发起新的请求会取消未完成的
                 binding.tvResult.text = result
             }

+ 2 - 2
sample/src/main/java/com/drake/net/sample/ui/fragment/UploadFileFragment.kt

@@ -23,8 +23,8 @@ import com.drake.net.Post
 import com.drake.net.component.Progress
 import com.drake.net.interfaces.ProgressListener
 import com.drake.net.sample.R
-import com.drake.net.sample.contract.AlbumSelectContract
 import com.drake.net.sample.constants.Api
+import com.drake.net.sample.contract.AlbumSelectContract
 import com.drake.net.sample.databinding.FragmentUploadFileBinding
 import com.drake.net.utils.TipUtils
 import com.drake.net.utils.scopeNetLife
@@ -69,7 +69,7 @@ class UploadFileFragment : EngineFragment<FragmentUploadFileBinding>(R.layout.fr
 
     private fun uploadUri(uri: Uri?) {
         scopeNetLife {
-            Post<String>("upload") {
+            Post<String>(Api.UPLOAD) {
                 param("file", uri)
                 addUploadListener(object : ProgressListener() {
                     override fun onProgress(p: Progress) {

+ 3 - 3
sample/src/main/java/com/drake/net/sample/ui/fragment/converter/FastJsonConvertFragment.kt

@@ -21,7 +21,7 @@ import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.converter.FastJsonConverter
 import com.drake.net.sample.databinding.FragmentCustomConvertBinding
-import com.drake.net.sample.model.HomeBannerModel
+import com.drake.net.sample.model.GameModel
 import com.drake.net.utils.scopeNetLife
 
 
@@ -35,9 +35,9 @@ class FastJsonConvertFragment :
         """.trimIndent()
 
         scopeNetLife {
-            binding.tvFragment.text = Get<List<HomeBannerModel>>(Api.BANNER) {
+            binding.tvFragment.text = Get<GameModel>(Api.GAME) {
                 converter = FastJsonConverter() // 单例转换器, 此时会忽略全局转换器
-            }.await()[0].desc
+            }.await().list[0].name
         }
     }
 

+ 3 - 3
sample/src/main/java/com/drake/net/sample/ui/fragment/converter/GsonConvertFragment.kt

@@ -21,7 +21,7 @@ import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.converter.GsonConverter
 import com.drake.net.sample.databinding.FragmentCustomConvertBinding
-import com.drake.net.sample.model.HomeBannerModel
+import com.drake.net.sample.model.GameModel
 import com.drake.net.utils.scopeNetLife
 
 
@@ -37,9 +37,9 @@ class GsonConvertFragment :
         """.trimIndent()
 
         scopeNetLife {
-            binding.tvFragment.text = Get<List<HomeBannerModel>>(Api.BANNER) {
+            binding.tvFragment.text = Get<GameModel>(Api.GAME) {
                 converter = GsonConverter() // 单例转换器, 此时会忽略全局转换器, 在Net中可以直接解析List等嵌套泛型数据
-            }.await()[0].desc
+            }.await().list[0].name
         }
     }
 

+ 3 - 3
sample/src/main/java/com/drake/net/sample/ui/fragment/converter/MoshiConvertFragment.kt

@@ -21,7 +21,7 @@ import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.converter.MoshiConverter
 import com.drake.net.sample.databinding.FragmentCustomConvertBinding
-import com.drake.net.sample.model.HomeBannerModel
+import com.drake.net.sample.model.GameModel
 import com.drake.net.utils.scopeNetLife
 
 
@@ -38,9 +38,9 @@ class MoshiConvertFragment :
         """.trimIndent()
 
         scopeNetLife {
-            binding.tvFragment.text = Get<List<HomeBannerModel>>(Api.BANNER) {
+            binding.tvFragment.text = Get<GameModel>(Api.GAME) {
                 converter = MoshiConverter() // 单例转换器, 此时会忽略全局转换器
-            }.await()[0].desc
+            }.await().list[0].name
         }
     }
 

+ 3 - 3
sample/src/main/java/com/drake/net/sample/ui/fragment/converter/SerializationConvertFragment.kt

@@ -21,7 +21,7 @@ import com.drake.net.sample.R
 import com.drake.net.sample.constants.Api
 import com.drake.net.sample.converter.SerializationConverter
 import com.drake.net.sample.databinding.FragmentCustomConvertBinding
-import com.drake.net.sample.model.HomeBannerModel
+import com.drake.net.sample.model.GameModel
 import com.drake.net.utils.scopeNetLife
 
 class SerializationConvertFragment :
@@ -38,12 +38,12 @@ class SerializationConvertFragment :
         """.trimIndent()
 
         scopeNetLife {
-            val data = Get<List<HomeBannerModel>>(Api.BANNER) {
+            val data = Get<GameModel>(Api.GAME) {
                 // 该转换器直接解析JSON中的data字段, 而非返回的整个JSON字符串
                 converter = SerializationConverter() // 单例转换器, 此时会忽略全局转换器
             }.await()
 
-            binding.tvFragment.text = data[0].desc
+            binding.tvFragment.text = data.list[0].name
         }
     }
 

+ 3 - 3
sample/src/main/java/com/drake/net/sample/vm/UserViewModel.kt

@@ -19,15 +19,15 @@ class UserViewModel : ViewModel() {
      * scopeNetLife/scopeDialog不推荐写在ViewModel中
      */
     fun fetchUserInfo() = scopeNetLife {
-        userInfo.value = Get<String>(Api.BANNER).await()
+        userInfo.value = Get<String>(Api.GAME).await()
     }
 
     /** 返回Deferred, 可以灵活使用, 支持并发组合 */
-    fun CoroutineScope.fetchList() = Get<String>(Api.BANNER)
+    fun CoroutineScope.fetchList() = Get<String>(Api.TEST)
 
     /** 直接返回数据, 会阻塞直至数据返回 */
     suspend fun fetchPrecessData() = coroutineScope {
-        val response = Get<String>(Api.BANNER).await()
+        val response = Get<String>(Api.TEST).await()
         response + "处理数据"
     }
 }

+ 20 - 0
sample/src/main/res/drawable/bg_input.xml

@@ -0,0 +1,20 @@
+<?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.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <corners android:radius="8dp" />
+    <solid android:color="#646464" />
+</shape>

+ 16 - 8
sample/src/main/res/layout/fragment_view_model_request.xml

@@ -21,19 +21,27 @@
             android:id="@+id/btnFetchUserinfo"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="拉取用户信息" />
+            android:text="拉取用户信息"
+            android:textStyle="bold" />
 
-        <TextView
-            android:id="@+id/tvResponse"
+        <ScrollView
             android:layout_width="match_parent"
             android:layout_height="400dp"
             android:layout_marginHorizontal="20dp"
             android:layout_marginTop="20dp"
-            android:background="@color/divider"
-            android:maxLines="300"
-            android:padding="8dp"
-            android:scrollbars="vertical"
-            android:text="@{m.userInfo}" />
+            android:background="@drawable/bg_input"
+            android:fadeScrollbars="true"
+            android:fillViewport="true">
+
+            <TextView
+                android:id="@+id/tvResponse"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="8dp"
+                android:text="@{m.userInfo}"
+                android:textColor="#FFFFFF" />
+
+        </ScrollView>
 
     </LinearLayout>
 </layout>

+ 1 - 1
sample/src/main/res/layout/item_list.xml

@@ -21,7 +21,7 @@
 
         <variable
             name="m"
-            type="com.drake.net.sample.model.CommonWebsite" />
+            type="com.drake.net.sample.model.GameModel.Data" />
     </data>
 
     <LinearLayout

+ 2 - 2
sample/src/main/res/layout/item_pull_list.xml

@@ -21,7 +21,7 @@
 
         <variable
             name="m"
-            type="com.drake.net.sample.model.HomeArticleModel.Data" />
+            type="com.drake.net.sample.model.GameModel.Data" />
     </data>
 
     <LinearLayout
@@ -40,7 +40,7 @@
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:gravity="center"
-                android:text="@{m.title}"
+                android:text="@{m.name}"
                 android:textStyle="bold"
                 tools:text="1" />
 

+ 173 - 0
sample/src/main/res/raw/game.json

@@ -0,0 +1,173 @@
+{
+  "total": 3,
+  "list": [
+    {
+      "id": 1,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202206/0301/KSalsBYWb0IuDrdD1SbptAd6.png?w=620&thumb=false",
+      "name": "Jett: The Far Shore",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "238.00",
+      "initialPrice": "238.00",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 2,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202109/2821/KkIiB8w4CBvZspu6zyzOza3p.png?w=620&thumb=false",
+      "name": "TOEM",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 3,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202208/0813/u7s4uL4Z0GPWfhOocyUT4WTp.png?w=620&thumb=false",
+      "name": "The Great Ace Attorney Chronicles",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 4,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202206/1621/OEZOTYnG11FGrewAwYdJ3EQF.png?w=620&thumb=false",
+      "name": "DEATHLOOP",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 5,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202206/0720/eEczyEMDd2BLa3dtkGJVE9Id.png?w=620&thumb=false",
+      "name": "奇异人生:本色",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 6,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202207/1823/uGwz6VetgE8k5BpCPKBD1qTj.png?w=620&thumb=false",
+      "name": "Hades",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 7,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202203/0209/hzUG7fe9HSXK9JfHYQM6V6Ad.png?w=620&thumb=false",
+      "name": "意航员2",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 8,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202105/0718/2gh2zdt2MQCLWLGkB9HTPGmR.png?w=620&thumb=false",
+      "name": "Ratchet & Clank: Rift Apart",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 9,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202206/0300/E2vZwVaDJbhLZpJo7Q10IyYo.png?w=620&thumb=false",
+      "name": "Resident Evil Village",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 10,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202206/0919/hq6KtnlrPbnUj7iNNI0V6gwe.png?w=620&thumb=false",
+      "name": "Returnal",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 11,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202203/0501/FUr3M0kGxyddUfUeuKBBFf2w.png?w=620&thumb=false",
+      "name": "Disco Elysium 一 The Final Cut",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    },
+    {
+      "id": 12,
+      "img": "https://image.api.playstation.com/vulcan/ap/rnd/202204/0118/A3KKgFFUTjKoxSc4ssAs61nF.png?w=620&thumb=false",
+      "name": "双人成行 PS4™ 和 PS5™",
+      "label": [
+        "中文",
+        "史低"
+      ],
+      "price": "207.01",
+      "initialPrice": "207.01",
+      "grade": 87,
+      "discount": 0.7,
+      "endTime": 123123131
+    }
+  ]
+}