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

Kotlin中OkHttp解析数据到RecyclerView时崩溃问题求助

问题排查与解决方案

核心原因

报错android.view.ViewRootImpl$CalledFromWrongThreadException明确说明:只有创建View层级的原始线程(主线程/UI线程)才能操作View。而OkHttp的enqueue异步回调(onResponse方法)是在后台子线程执行的,你直接在这个方法里修改noBankView的可见性、初始化RecyclerView的布局管理器和适配器,属于跨线程操作UI,直接触发了崩溃。

修复步骤

1. 将UI操作切换到主线程

把onResponse里的UI相关代码,用runOnUiThread包裹,或者用Handler.post(和你在onFailure里的写法一致),确保UI操作在主线程执行。

2. 提前初始化View变量

不要在网络回调里重复调用findViewById,建议在Activity的onCreate方法中提前初始化所有需要用到的View,避免重复查找,提升性能。

3. 优化空安全处理

避免用!!强制解包(比如saveBankResponseModel.data!!),改用空安全操作符?.配合let,防止空指针异常。

修改后的Activity关键代码

// 提前在Activity onCreate里初始化View
private lateinit var noBankView: LinearLayout
private lateinit var newRecyclerView: RecyclerView

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.your_activity_layout)
    // 初始化View
    noBankView = findViewById(R.id.nobank_layout)
    newRecyclerView = findViewById(R.id.recyclerView)
    // 发起网络请求
    callBankApi()
}

private fun callBankApi() {
    okHttpClient.newCall(request).enqueue(object : Callback {
        override fun onResponse(call: Call, response: Response) {
            if(response.isSuccessful) {
                val saveBankResponseModel = json.decodeFromString<SaveBankResponseModel>(
                    response.body!!.string()
                )
                Log.d("Member Bank API","${saveBankResponseModel.data?.memberBank}")
                
                // 将UI操作切换到主线程
                runOnUiThread {
                    saveBankResponseModel.data?.memberBank?.let { bankList ->
                        noBankView.visibility = View.GONE
                        newRecyclerView.apply {
                            layoutManager = LinearLayoutManager(this@MyWalletActivity)
                            adapter = SavedBankAdapter(bankList)
                        }
                    } ?: run {
                        // 处理data为null的情况,比如显示noBankView
                        noBankView.visibility = View.VISIBLE
                    }
                }
            }
        }

        override fun onFailure(call: Call, e: IOException) {
            runOnUiThread {
                Log.e("Bank API Error", e.message ?: "Unknown error")
                // 失败时可以显示错误提示
                noBankView.visibility = View.VISIBLE
            }
        }
    })
}

其他优化建议

  1. 适配器命名规范:Kotlin类名建议用大驼峰命名,把saved_bank_adapter改为SavedBankAdapter。
  2. 补全ViewHolder实现:你的适配器代码里缺少BankViewHolder的完整实现,需要补全:
inner class BankViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val itemName: TextView = itemView.findViewById(R.id.bank_name) // 替换为你的布局ID
    val itemAccNum: TextView = itemView.findViewById(R.id.bank_acc_number) // 替换为你的布局ID
}
  1. 避免全局变量滥用:不要把saveBankResponseModel作为全局变量,直接在onResponse里局部声明即可,减少内存泄漏风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 11:15:46