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

如何在Main Activity中获取已同步Realm实例?解决lateinit未初始化问题

realm=MyApp.Databaseobject.realm // 本地数据库初始化正常
realmSynched= ???? // 不知道怎么初始化这个

---

## 解决方案
### 方法一:在MainActivity中用生命周期协程异步初始化
直接在MainActivity里用`lifecycleScope`处理同步Realm的初始化,避免用`runBlocking`阻塞主线程,同时确保初始化完成后再使用实例。

```kotlin
lateinit var realm: Realm
private var realmSynched: Realm? = null

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

    // 初始化本地Realm
    realm = MyApp.Databaseobject.realm

    // 异步初始化同步Realm
    lifecycleScope.launch {
        val appid = "MYAppId"
        val apikey = "MyApiKey"
        val app = App.create(
            AppConfiguration.Builder(appid)
                .log(LogLevel.ALL)
                .build()
        )
        val userApi = app.login(Credentials.apiKey(apikey))
        val config = SyncConfiguration.Builder(
            userApi,
            setOf(MyClass::class)
        )
            .initialSubscriptions { realm ->
                add(
                    realm.query<PersonCollection>("MyField == $0", "Mustermann"),
                    "subscription name"
                )
            }
            .build()
        realmSynched = Realm.open(config)
        // 初始化完成后再执行依赖同步Realm的操作
        useSyncedRealm()
    }
}

private fun useSyncedRealm() {
    realmSynched?.let { realm ->
        // 这里正常使用同步Realm
        val targetPersons = realm.query<PersonCollection>().find()
        // 业务逻辑处理
    } ?: run {
        // 处理初始化未完成的情况,比如显示加载提示
    }
}

override fun onDestroy() {
    super.onDestroy()
    realm.close()
    realmSynched?.close() // 记得关闭同步Realm释放资源
}

方法二:用单例类统一管理同步Realm

封装一个单例类,把同步Realm的初始化逻辑放在里面,确保全局只初始化一次,同时提供安全的实例获取方法。

object SyncedRealmManager {
    private var realmSynched: Realm? = null
    private val initLock = Any() // 加锁避免多线程重复初始化

    suspend fun getSyncedRealm(): Realm? {
        synchronized(initLock) {
            if (realmSynched == null || realmSynched!!.isClosed()) {
                val appid = "MYAppId"
                val apikey = "MyApiKey"
                val app = App.create(
                    AppConfiguration.Builder(appid)
                        .log(LogLevel.ALL)
                        .build()
                )
                val userApi = app.login(Credentials.apiKey(apikey))
                val config = SyncConfiguration.Builder(
                    userApi,
                    setOf(MyClass::class)
                )
                    .initialSubscriptions { realm ->
                        add(
                            realm.query<PersonCollection>("MyField == $0", "Mustermann"),
                            "subscription name"
                        )
                    }
                    .build()
                realmSynched = Realm.open(config)
            }
            return realmSynched
        }
    }

    fun closeSyncedRealm() {
        realmSynched?.close()
        realmSynched = null
    }
}

然后在MainActivity中调用:

lateinit var realm: Realm
private var realmSynched: Realm? = null

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

    realm = MyApp.Databaseobject.realm

    lifecycleScope.launch {
        realmSynched = SyncedRealmManager.getSyncedRealm()
        useSyncedRealm()
    }
}

private fun useSyncedRealm() {
    realmSynched?.let {
        // 使用同步Realm处理业务
    }
}

override fun onDestroy() {
    super.onDestroy()
    realm.close()
    SyncedRealmManager.closeSyncedRealm()
}

关键注意点

  1. 绝对不要在主线程用runBlocking,会导致UI卡顿甚至ANR,改用Android提供的生命周期协程(lifecycleScope/viewModelScope)处理异步操作。
  2. 同步Realm的初始化是异步过程,必须等初始化完成后再使用,不能直接给lateinit var赋值(因为无法保证初始化完成时机),建议用可空变量配合空安全调用。
  3. 所有Realm实例在使用完后必须调用close(),避免内存泄漏,最好在Activity的onDestroy()方法中处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:05:24