Retrofit中使用@Path传递page参数引发应用崩溃的问题求助
Retrofit中使用@Path传递page参数引发应用崩溃的问题求助
兄弟,我看了你的代码和报错日志,问题其实一眼就能看出来!你把Retrofit里的@Path和@Query用混了,这才导致应用直接崩溃。
问题根源分析
先看Logcat里的核心报错信息:
java.lang.IllegalArgumentException: URL query string "exclude=data&limit=1&fields=title%2Cimage_id%2Cdate_display%2Cartist_title%2Cshort_description&page={id}" must not have replace block. For dynamic query parameters use @Query.
Retrofit的注解分工很明确:
@Path是用来替换URL路径中的占位符的,比如/api/v1/artworks/{artworkId}这种路径里的{artworkId}才适合用它;- 而你要传的
page是URL末尾的查询参数(就是?后面跟的键值对),这种情况必须用@Query注解来传递,不能硬把占位符写在查询字符串里再用@Path替换。
具体修改方案
1. 修正ApiInterface接口
把错误的@Path改成@Query,同时调整GET请求的URL,去掉查询字符串里的page={id}:
interface ApiInterface { @GET("/api/v1/artworks?exclude=data&limit=1&fields=title%2Cimage_id%2Cdate_display%2Cartist_title%2Cshort_description") suspend fun GetDataArr(@Query("page") page: Int): Response<Artic> }
如果你想让代码更规范、更灵活,也可以把所有查询参数都用@Query定义,固定参数给默认值,还能避免手动转义特殊字符(比如逗号不用写%2C,直接写逗号就行,Retrofit会自动处理URL编码):
interface ApiInterface { @GET("/api/v1/artworks") suspend fun GetDataArr( @Query("page") page: Int, @Query("exclude") exclude: String = "data", @Query("limit") limit: Int = 1, @Query("fields") fields: String = "title,image_id,date_display,artist_title,short_description" ): Response<Artic> }
2. 其他优化建议(避免后续踩坑)
- 别再用
GlobalScope了,官方早就不推荐了,建议用viewModelScope或者自定义的CoroutineScope,能有效避免内存泄漏; - 你在
catch块里调用Toast的时候,要切换到主线程!因为Toast必须在主线程显示,现在你在Dispatchers.IO里直接调用会有问题,改成这样:
catch (e: HttpException) { withContext(Dispatchers.Main) { Toast.makeText(applicationContext, "http error: ${e.message}", Toast.LENGTH_SHORT).show() } return@launch }
- 别用
response.body()!!这种强制非空写法,万一body为空会直接抛空指针,建议先判空处理:
response.body()?.let { articData.value = it } ?: run { withContext(Dispatchers.Main) { Toast.makeText(applicationContext, "返回数据为空", Toast.LENGTH_SHORT).show() } }
内容来源于stack exchange
相关产品推荐
相关产品推荐

