网络请求demo

Android Basics in Kotlin course

retrofit文档页面

准备工作

  • 添加 Retrofit 依赖,在应用级 build.gradle 中添加
// Retrofit
implementation "com.squareup.retrofit2:retrofit:2.9.0"
// Retrofit with Moshi Converter
implementation "com.squareup.retrofit2:converter-scalars:2.9.0"

前者是 Retrofit2 库本身, 后者用于 Retrofit 标量转换器。此转换器允许 Retrofit 将 JSON 结果作为 String 返回。这两个库协同工作。

  • 添加对 Java8 语言功能的支持,在应用级 build.gradle 中 android 栏目里添加

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  kotlinOptions {
    jvmTarget = '1.8'
  }
  

demo详细步骤

创建 PictureApiService 类网络层服务

添加 Retrofit 构建器以构建和创建 Retrofit 对象。

private const val BASE_URL = "https://imgapi.cn/"

private val retrofit = Retrofit.Builder()
   .addConverterFactory(ScalarsConverterFactory.create())
   .baseUrl(BASE_URL)
   .build()

Retrofit 包含一个 ScalarsConverter,它支持字符串和其他基元类型,使用 ScalarsConverterFactory 实例对构建器调用 addConverterFactory()。此时,Retrofit 从网络服务获取 JSON 相应,并将该相应作为 String 返回。使用 baseUrl() 方法添加网络服务的基础 URI。

获取相应字符串

interface PictureApiService {
    @GET("api.php?fl=fengjing&gs=json")
    suspend fun getPhotos(): String
}

在 PictureApiService 界面中,添加一个名为 getPhotos() 的函数,以从网络服务中获取响应字符串。使用 @GET 注解告知 Retrofit 这是 GET 请求,并为该网络服务方法指定端点。系统会自动导入 retrofit2.http.GET 包,

声明单例对象

object PictureApi {
    val retrofitService: PictureApiService by lazy {
        retrofit.create(PictureApiService::class.java)
    }
}

PictureApi 对象声明内,添加一个名为 retrofitService、类型为 PictureApiService 的逐个初始化的 Retrofit 对象属性。by lazy 可以进行惰性初始化,以确保其在首次使用时进行初始化。

接下来可以全局访问单例对象

调用网络服务

    viewModeScope.launch {
        Log.d("json", PictureApi.retrofitService.getPhotos())
    }

运行后会在日志中打印获取的json字符串。

moshi 解析 json 字符串

  1. 修改库依赖
  2. 定义一个数据类储存解析后的结果
  3. 调用网络服务

将上述依赖改为:

// Moshi
implementation 'com.squareup.moshi:moshi-kotlin:1.9.3'
// Retrofit with Moshi Converter
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'

创建数据类:

import com.squareup.moshi.Json

data class MyPicture(
    val code: String,
    @Json(name = "imgurl") val imgSrcUrl: String,
    val width: String,
    val height: String
)

@Json 注解将变量 imgSrcUrl 映射到 Json 属性 imgurl


修改PictureApiService.kt

private const val BASE_URL = "https://imgapi.cn/"

private val moshi = Moshi.Builder()
    .add(KotlinJsonAdapterFactory())
    .build()

private val retrofit = Retrofit.Builder()
    .addConverterFactory(MoshiConverterFactory.create(moshi))
    .baseUrl(BASE_URL)
    .build()

interface PictureApiService {
    @GET("api.php?fl=fengjing&gs=json")
    suspend fun getPhotos(): MyPicture
}

object PictureApi {
    val retrofitService: PictureApiService by lazy {
        retrofit.create(PictureApiService::class.java)
    }
}