我正在编写一个图书搜索应用程序。在其中,我创建了一个 Retrofit 服务来从 Google Books API 获取数据。 当我多次使用 q=domani 查询时,有时每次查询结果都不一样。
下面是在视图模型中执行查询的代码:
fun getPhotos(query: String) {
viewModelScope.launch {
fetchUiState = FetchUiState.Loading
fetchUiState = try {
var thumbnails = bookRepository.getBooks(query)
.items.map { it.volumeInfo.imageLinks?.thumbnail }
thumbnails=thumbnails.filterNotNull()
Log.d("getPhotos", "${thumbnails.size} Thumbnails: $thumbnails")
FetchUiState.Success(thumbnails)
} catch (e: HttpException) {
Log.e("getPhotos", "HTTP exception occurred", e)
FetchUiState.Error
} catch (e: IOException) {
Log.e("getPhotos", "Network or IO exception occurred", e)
FetchUiState.Error
} catch (e: Exception) {
Log.e("getPhotos", "Unexpected exception occurred", e)
FetchUiState.Error
}
}
}
改造声明:
interface BookApiService{
@GET("volumes")suspend fun getBooks(@Query("q") query: String): QueryResult
}
interface AppContainer {
val bookRepository: BookRepository
}
class DefaultAppContainer : AppContainer {
private val json = Json {
ignoreUnknownKeys = true
}
private val baseUrl="https://www.googleapis.com/books/v1/"
private val retrofit: Retrofit = Retrofit.Builder()
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.baseUrl(baseUrl)
.build()
private val retrofitService: BookApiService by lazy {
retrofit.create(BookApiService::class.java)
}
override val bookRepository: BookRepository by lazy {
NetWorkBookRepository(retrofitService)
}
}
数据层:
@Serializable
data class QueryResult(
val items: List<BookInfo>
)
@Serializable
data class BookInfo(
val id: String,
val volumeInfo: VolumeInfo
)
@Serializable
data class VolumeInfo(
val imageLinks: ImageLinks? = null,
)
@Serializable
data class ImageLinks(
val thumbnail: String
)
您观察到的行为的原因是分页。 Books API 不会一次返回所有搜索结果,而是默认返回 10 个批次。您可以通过从浏览器调用 URL 来测试它:
https://www.googleapis.com/books/v1/volumes?q=domani
请查看官方文档:
分页 您可以通过在请求的参数中指定两个值来对卷列表进行分页:
- 集合中开始的位置。第一项的索引为 0。startIndex
- 要返回的最大结果数。默认值为 10,最大允许值为 40。maxResults
因此,每次执行请求时,API 可能会返回不同批次的 10 个搜索结果。在这 10 个搜索结果中,可能有不同数量的结果分配有您要过滤的缩略图。