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

Android Kotlin中Realm加载Activity崩溃,报ClientErrorCode:3错误求助

解决Realm数据加载崩溃及Logcat ClientErrorCode:3问题

你的问题核心出在Realm对象的线程绑定特性和数据加载与UI更新的时机不匹配上,我帮你一步步拆解修复:

核心问题分析

  • Realm对象线程不安全:你在后台线程(若启用AsyncTask)获取的ChattRItem实例绑定到该线程的Realm对象,当你关闭Realm后这些对象会立即失效,直接传递到UI线程使用会触发崩溃。
  • 数据加载与UI更新不同步:当前你注释了AsyncTask,同步调用loadFromRealm会阻塞UI线程,且runOnUiThread立即执行时chattRItemList还未填充,Adapter拿到空列表;后续数据加载完成也没有通知Adapter更新。
  • ClientErrorCode:3:该错误通常和Realm线程访问违规、实例管理不当有关,修复上述线程问题后会自然消失。

具体修复方案

1. 重构Realm使用方式,UI线程管理实例

Realm推荐在UI线程使用实例,并通过RealmChangeListener监听数据变化,避免线程绑定问题同时支持自动更新:

class EssentialsActivity : AppCompatActivity() {
    private var category: String? = null
    private lateinit var realm: Realm
    private var realmResults: RealmResults<ChattRItem>? = null
    private lateinit var essentialsAdapter: EssentialsAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_essentials)

        // 初始化UI线程Realm实例
        Realm.init(this)
        realm = Realm.getDefaultInstance()
        category = "People"

        // 配置RecyclerView
        recyclerView_Essentials.setBackgroundColor(Color.CYAN)
        recyclerView_Essentials.layoutManager = GridLayoutManager(this, 3)
        essentialsAdapter = EssentialsAdapter(emptyList())
        recyclerView_Essentials.adapter = essentialsAdapter

        // 异步加载数据并监听变化
        loadFromRealm(category!!)
    }

    private fun loadFromRealm(category: String) {
        // 异步查询避免阻塞UI
        realmResults = realm.where(ChattRItem::class.java)
            .equalTo("itemCategory", category)
            .findAllAsync()

        // 监听数据变化,更新Adapter
        realmResults?.addChangeListener { results ->
            // 拷贝为非Realm托管对象,安全跨线程使用
            val itemList = realm.copyFromRealm(results)
            essentialsAdapter.updateData(itemList)
        }
    }

    // 修复菜单跳转逻辑
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.categories, menu)
        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        return when (item?.itemId) {
            R.id.addItem_menu_item -> {
                val intent = Intent(this, AddItemActivity::class.java)
                intent.putExtra("category", category)
                startActivity(intent)
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    // 清理Realm资源,防止内存泄漏
    override fun onDestroy() {
        super.onDestroy()
        realmResults?.removeAllChangeListeners()
        realm.close()
    }
}

2. 修改Adapter支持动态更新数据

给Adapter添加updateData方法,接收新数据并通知RecyclerView刷新:

class EssentialsAdapter(private var chattRItemList: List<ChattRItem>) : RecyclerView.Adapter<CustomViewHolder>() {

    override fun getItemCount(): Int = chattRItemList.size

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        val chattRItem = chattRItemList[position]
        holder.bind(chattRItem)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val cellForRow = layoutInflater.inflate(R.layout.essentials_cells_layout, parent, false)
        return CustomViewHolder(cellForRow)
    }

    // 动态更新数据并刷新列表
    fun updateData(newList: List<ChattRItem>) {
        chattRItemList = newList
        notifyDataSetChanged()
    }
}

class CustomViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    fun bind(chattRitem: ChattRItem) {
        itemView.textView_essentials_name.text = chattRitem.itemName
    }
}

3. 关键说明

  • copyFromRealm的作用:将Realm托管对象拷贝为普通Kotlin对象,脱离Realm实例绑定,可安全在UI线程使用,不会因Realm关闭而失效。
  • 异步查询findAllAsync:避免UI线程同步查询阻塞界面,查询完成后通过监听器回调通知数据就绪。
  • Realm生命周期管理:在onDestroy关闭实例并移除监听器,防止内存泄漏。

验证修复

  1. Logcat的ClientErrorCode:3错误会消失,不再存在跨线程使用Realm对象的问题。
  2. EssentialsActivity加载时不再崩溃,RecyclerView会正确展示itemName。
  3. Realm数据变化时,RecyclerView会自动刷新显示最新内容。

如果仍有问题,可提供完整崩溃Logcat信息,我再帮你进一步排查。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:38:30