处理Android改造的工作流程
#kotlin #android #mobile #tristan

目录

  1. Read First
  2. My workflow
  3. Use Postman to query endpoint
  4. Model response object
  5. Create method in interface
  6. Create method in Repository

代码

YouTube版本

简介

  • 我已经开始了我的下一个应用程序,这是一个Twitch客户端应用。这个系列将是我创建此应用时所面临的所有笔记和问题。

阅读第一个

  • 本教程已经假设您熟悉Retrofit,并且在应用程序中启动并运行了Raterofit。本教程旨在成为一个更抽象的指南,并使个人对我的工作流程有广泛的了解。不要过多地关注细节,这是该工作流程中最有用的一系列步骤

使用翻新时的工作流程

  • 当我与Twitch API合作时,我一直在进行改造。如此之多,以至于当我需要调用API的新端点时,我已经开发了一些工作流程。工作流由4个步骤组成:

1)使用Postman查询端点
2)对响应对象进行建模
3)在Retrofit接口中创建方法
4)在存储库层中创建方法

1)使用Postman查询端点

  • 文档只能告诉我们太多,有时可能会过时或不正确。这就是为什么在开始编码之前,我喜欢用Postman查询端点的原因。这有两个主要好处:

1)验证我们正在使用所有适当的标头和参数击中适当的端点。

2)为我们提供了一个适当的示例,说明了响应对象是什么。我们必须验证响应对象是否在JSON中也很重要。 JSON是Retrofit将用于转换为我们的Kotlin对象的适当格式

2)响应对象建模

  • 因此,假设我们正在使用get-streams API端点。经过成功的响应,我们将获得一个看起来像这样的JSON对象:
"data": [
        {
            "id": "40457151671",
            "user_id": "582765062",
            "user_login": "premiertwo",
            "user_name": "PremierTwo",
            "game_id": "33214",
            "game_name": "Fortnite",
            "type": "live",
            "title": "fork knife @rubberross @ironmouse @aicandii | Tokyo, Japan | !discord",
            "viewer_count": 3506,
            "started_at": "2023-07-17T08:14:13Z",
            "language": "en",
            "thumbnail_url": "https://static-cdn.jtvnw.net/previews-ttv/live_user_premiertwo-{width}x{height}.jpg",
            "tag_ids": [],
            "tags": [
                "Improv",
                "Forehead",
                "AMA",
                "VoiceActing",
                "Japan",
                "Travel",
                "English",
                "NoSpoilers"
            ],
            "is_mature": false
        },
]


  • 我们建模的响应对象将看起来像这样:
data class FollowedLiveStreams(
    val data:List<StreamData>
)

data class StreamData(
    val id:String,
    @SerializedName("user_id")
    val userId:String,
    @SerializedName("user_login")
    val userLogin:String,
    @SerializedName("user_name")
    val userName:String,
    @SerializedName("game_id")
    val gameId:String,
    @SerializedName("game_name")
    val gameName:String,
    val type:String,
    val title:String,
    @SerializedName("viewer_count")
    val viewerCount:Int,
    @SerializedName("started_at")
    val startedAt:String,
    val language:String,
    @SerializedName("thumbnail_url")
    val thumbNailUrl:String,
    @SerializedName("tag_ids")
    val tagIds:List<String>,
    val tags:List<String>,
    @SerializedName("is_mature")
    val isMature:Boolean

)
  • 尝试建模JSON响应对象时,您应该寻找两件事:

1)[]方括号:表示列表。这就是为什么KOTLIN数据类版本"tags": ["Improv"]val tags:List<String>

2){}卷曲括号:指示一个新对象。这就是为什么我们将JSON响应对象建模为两个类的原因。请注意,其"data": [ {是如何的,紧随其后的方括号是卷曲括号告诉我们data是对象的列表。这导致我们的data:List<StreamData>

3)在翻新接口中创建方法

  • 现在是我们修改将表示HTTP调用的接口的部分。假设我们仍在使用get-streams API,则该呼叫看起来像这样:
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Query

@GET("streams/followed")
    suspend fun getFollowedStreams(
        @Header("Authorization") authorization:String,
        @Header("Client-Id") clientId:String,
        @Query("user_id") userId:String
    ): Response<FollowedLiveStreams>

  • 请注意,我们如何使用@Header@Query来定义查询参数和标题的动态值。另外,看看返回对象是Response<FollowedLiveStreams>,我们正在使用以前创建的FollowedLiveStreams。改造将自动将JSON对象映射到我们的FollowedLiveStreams对象

4)在存储库层中创建方法

  • 现在,在存储库层的内部,我们可以将实际调用API进行,就像这样:
class TwitchRepoImpl(
    private val twitchClient: TwitchClient = TwitchRetrofitInstance.api
) {
suspend fun getFollowedLiveStreams(
        authorizationToken: String,
        clientId: String,
        userId: String
    ): Flow<Response<FollowedLiveStreams>> = flow{
        emit(Response.Loading)
        val response = twitchClient.getFollowedStreams(
            authorization = authorizationToken,
            clientId = clientId,
            userId = userId
        )
        if (response.isSuccessful){
           emit(response.body())
        }else{
          emit(Response.Failure(Exception("Error!, code {${response.code()}}")))

        }
    }

}

  • 上面的代码似乎有些混乱,但要澄清事物,响应对象是我自己的创建:
sealed class Response<out T> {


    object Loading: Response<Nothing>()


    data class Success<out T>(
        val data:T
    ):Response<T>()


    data class Failure(
        val e:Exception
    ):Response<Nothing>()

}
  • 我正在从getFollowedLiveStreams()返回Kotlin Flows,因此我的下游类(viewModels)能够在这种方法上调用collect{},并根据响应是加载,成功或失败

  • 而做出不同的反应。
  • 我们定义了存储库层内部的方法后,我们可以随意使用该方法。

结论

  • 感谢您抽出宝贵的时间阅读我的博客文章。如果您有任何疑问或疑虑,请在下面发表评论或在Twitter上与我联系。