如何用Retrofit发送请求?获取M3U8响应时遇JSON格式错误
解决Retrofit获取M3U8文本时的JSON解析错误
问题核心
你遇到的错误根源很明确:目标接口返回的是M3U8纯文本格式,但你的Retrofit配置了GsonConverterFactory,会强制把响应内容当成JSON解析,自然会抛出格式不匹配的异常。另外你的RestClient里的BASE_URL和实际请求的S3地址不匹配,不过如果接口用了@Url注解的话,这个问题影响不大,但建议保持配置规范。
解决方案
1. 修改Retrofit接口定义
把接口返回类型从Call<JsonObject>改成Call<String>,因为我们要获取的是纯文本格式的M3U8内容:
interface ApiInterfaces { @GET fun getM3U8Content(@Url url: String): Call<String> }
2. 调整Retrofit配置(推荐)
如果项目里同时有JSON接口和纯文本接口,建议添加ScalarsConverterFactory来支持字符串、基本类型的解析,放在Gson转换器前面,保证优先级:
object RestClient { val BASE_URL = "http://gamecorner.sd.zain.com/" private var retrofit: Retrofit? = null private const val TIME_OUT = 30 val client: Retrofit? get() { if (retrofit == null) { retrofit = Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(ScalarsConverterFactory.create()) // 先添加纯文本转换器 .addConverterFactory(GsonConverterFactory.create()) .build() } return retrofit } }
注意:如果只需要处理这个M3U8请求,也可以单独创建一个不带Gson转换器的Retrofit实例,但添加Scalars转换器的方式更灵活,能兼容其他纯文本接口。
3. 修改API调用逻辑
现在回调里直接处理String类型的响应,无需再做JSON转换:
val apiService = RestClient.client!!.create(ApiInterfaces::class.java) val call = apiService.getM3U8Content("https://yash-out.s3.amazonaws.com/cat3/vid55/hls_55.m3u8") call.enqueue(object : Callback<String> { override fun onResponse(call: Call<String>, response: Response<String>) { if (response.isSuccessful) { val m3u8Content = response.body() // 这里拿到M3U8文本后,做你需要的处理(比如解析播放列表) binding.viewpager.visibility = View.VISIBLE binding.clProgressView.visibility = View.GONE } else { // 处理请求失败(响应码非2xx) recreate() } } override fun onFailure(call: Call<String>, t: Throwable) { t.printStackTrace() recreate() } })
额外注意
- 你原来的代码里试图把
JsonObject转成SliderItem,这和M3U8的用途完全不符,要确认是不是搞错了接口需求?如果这个M3U8是视频播放列表,应该解析文本内容,而非转成业务实体类。 - 确保添加了Scalars转换器的依赖(版本和你的Retrofit保持一致):
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
内容的提问来源于stack exchange,提问作者Affan Ahmed
相关产品推荐
相关产品推荐

