Android Studio中使用Retrofit重复查询结果不一致问题
问题:Google Books API多次查询结果不一致
我开发了一款图书搜索应用,通过Retrofit调用Google Books API获取数据,但多次执行q=domani查询时,返回的结果(缩略图列表)有时会不一致。
相关代码
ViewModel查询逻辑
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 } } }
Retrofit配置
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 )
日志表现
两次相同查询返回的缩略图数量不同,比如一次返回3个,一次返回2个,列表内容也存在差异。
原因分析
- Google Books API的动态特性:该API的搜索结果会根据内容更新、用户区域、服务器负载等因素动态调整,默认无固定排序或分页约束,导致多次请求结果不同。
- 缺少分页与排序参数:当前请求仅传入
q参数,未指定maxResults(返回结果数量)、startIndex(起始位置)和orderBy(排序方式),API会返回默认的可变结果集。 - 无本地缓存:每次请求直接调用远程API,没有缓存机制,无法保证相同查询的结果一致性。
解决方案
1. 固定API请求参数
修改BookApiService,添加分页和排序参数,确保每次请求的结果范围一致:
interface BookApiService{ @GET("volumes") suspend fun getBooks( @Query("q") query: String, @Query("maxResults") maxResults: Int = 10, // 固定返回数量 @Query("startIndex") startIndex: Int = 0, // 固定起始位置 @Query("orderBy") orderBy: String = "relevance" // 固定排序方式 ): QueryResult }
2. 实现本地缓存
使用Room或其他缓存库,对相同查询的结果进行缓存,优先读取缓存数据:
- 创建缓存实体类映射查询结果
- 在
NetWorkBookRepository中,先检查缓存是否存在对应查询结果,存在则返回缓存,否则请求API并更新缓存
3. 验证结果一致性
如果需要追踪结果变化,可记录每次返回的BookInfo.id列表,对比差异,确认是API返回变化还是本地处理逻辑问题。
内容的提问来源于stack exchange,提问作者Trần Thanh Vinh
相关产品推荐
相关产品推荐

