Android Studio Kotlin报错java.lang.IllegalStateException:预期对象却为数组
问题排查与解决方案
错误原因
java.lang.IllegalStateException: begin object but was begin array 是JSON解析类型不匹配导致的:你的代码用单个animalsound对象接收API响应,但实际接口返回的是animalsound类型的JSON数组(用[]包裹),解析器预期开头是对象{},却收到数组[],因此抛出异常。
修复步骤
1. 修改Retrofit接口声明
将接口返回类型从单个对象改为数组列表:
interface ApiInterface { // 原写法(错误) // @GET("your-api-path") // fun getanimalsound(): Call<animalsound> // 修改后(正确) @GET("your-api-path") fun getanimalsound(): Call<List<animalsound>> }
2. 适配回调中的响应处理
更新点击事件的回调逻辑,处理列表类型的响应:
binding.animalsoundimg.setOnClickListener { val call2 = apiinterface.getanimalsound() call2.enqueue(object : Callback<List<animalsound>> { override fun onResponse( call: Call<List<animalsound>>, response: Response<List<animalsound>> ) { if (response.isSuccessful) { // 按需取列表中的元素,示例取第一个有效项 val targetSound = response.body()?.firstOrNull() val soundUrl = targetSound?.soundurl if (soundUrl != null) { PlayAnimalSound(soundUrl) } else { Toast.makeText(applicationContext, "未获取到有效声音链接", Toast.LENGTH_SHORT).show() } } else { Toast.makeText(applicationContext, "请求失败:${response.code()}", Toast.LENGTH_SHORT).show() } } override fun onFailure(call: Call<List<animalsound>>, t: Throwable) { Toast.makeText(applicationContext, "错误:${t.message}", Toast.LENGTH_SHORT).show() } }) }
3. 优化MediaPlayer播放逻辑(可选但推荐)
原播放方法存在重复创建实例、同步prepare可能导致ANR的问题,优化后:
private fun PlayAnimalSound(soundurl: String) { // 释放旧实例,避免内存泄漏 mediaPlayer?.release() mediaPlayer = MediaPlayer().apply { try { setDataSource(soundurl) // 异步准备,避免阻塞主线程 prepareAsync() setOnPreparedListener { it.start() } setOnErrorListener { _, errCode, errExtra -> Toast.makeText(applicationContext, "播放失败:错误码$errCode", Toast.LENGTH_SHORT).show() true } } catch (e: Exception) { Toast.makeText(applicationContext, "播放器初始化失败:${e.message}", Toast.LENGTH_SHORT).show() } } }
额外提示
- 编码规范:Kotlin类名首字母需大写,建议将
animalsound改为AnimalSound,提升代码可读性。 - 若API预期返回单个对象,需联系后端修正响应格式(将数组改为单个JSON对象);若返回数组是设计预期,以上修改即可解决问题。
内容的提问来源于stack exchange,提问作者Babariya Rutviksinh
相关产品推荐
相关产品推荐

