You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击按钮打印数据时遇Expected BEGIN_ARRAY but was BEGIN_OBJECT错误求助

解决Gson解析错误:Expected BEGIN_ARRAY but was BEGIN_OBJECT

错误信息

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

问题根源

这个错误是Gson解析时的类型不匹配导致的:

  • 你的ViewModel里定义了MutableLiveData<List<PasswordModel>>,期望服务器返回数组格式(用[]包裹的多个对象)
  • 但实际服务器返回的是单个对象格式(用{}包裹的单个对象),Gson尝试把对象解析成数组时直接失败。
  • 另外MainActivity里直接调用viewModel.responsePassword.toString()是错误用法:LiveData是观察者模式的容器,直接toString()只能得到对象的内存地址,拿不到实际接口返回的数据。

修复步骤

1. 修正ViewModel的数据类型

把_response和responsePassword的类型从List<PasswordModel>改成单个PasswordModel,匹配接口返回的对象格式:

@HiltViewModel
class PasswordGeneratorViewModel @Inject constructor(private val repository: PasswordGeneratorRepository): ViewModel() {

    private val _response = MutableLiveData<PasswordModel>()
    val responsePassword: LiveData<PasswordModel>
        get() = _response

    init {
        getPassword()
    }

    private fun getPassword() = viewModelScope.launch {
        repository.getPasswordGenerate().let {response ->
            if (response.isSuccessful){
                _response.postValue(response.body())
            }else{
                Log.d("tag", "getPassword Error: ${response.code()}")
            }
        }
    }
}

2. 修正MainActivity的LiveData使用方式

通过observe方法监听LiveData的变化,数据更新时再将内容设置到TextView:

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val viewModel: PasswordGeneratorViewModel by viewModels()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 监听LiveData数据变化,更新UI
        viewModel.responsePassword.observe(this) { passwordModel ->
            passwordModel?.let {
                // 根据需求格式化展示char列表,比如用逗号拼接
                binding.password.text = it.char.joinToString(", ")
            }
        }

        binding.generatePassword.setOnClickListener {
            // 如果需要点击按钮才触发请求,把getPassword()从ViewModel的init移到这里
            // viewModel.getPassword()
        }
    }
}

3. 确认接口返回格式

如果你的接口设计上确实应该返回多个PasswordModel对象(数组格式),需要检查接口是否正常返回数组;如果接口就是返回单个对象,上面的修改即可解决问题。

内容的提问来源于stack exchange,提问作者Nisa Efendioglu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 18:58:33