如何在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() }
关键注意点
- 绝对不要在主线程用
runBlocking,会导致UI卡顿甚至ANR,改用Android提供的生命周期协程(lifecycleScope/viewModelScope)处理异步操作。 - 同步Realm的初始化是异步过程,必须等初始化完成后再使用,不能直接给
lateinit var赋值(因为无法保证初始化完成时机),建议用可空变量配合空安全调用。 - 所有Realm实例在使用完后必须调用
close(),避免内存泄漏,最好在Activity的onDestroy()方法中处理。
内容的提问来源于stack exchange,提问作者CrazyTaz
相关产品推荐
相关产品推荐

