【问题标题】:How can I use RealmResult loaded from background thread and use it in Android Main thread如何使用从后台线程加载的 RealmResult 并在 Android 主线程中使用它
【发布时间】:2019-11-05 01:12:34
【问题描述】:

在我的应用程序中,我使用ViewModel,我想将 Realm 实例和所有 CRUD 操作保留在后台线程中。 ViewModel 有一个MutableLiveData

data class User(val userId: Long, val name: String) : RealmModel

class UserViewModel : ViewModel() {

    private val realmThreadContext = Executors.newSingleThreadExecutor().asCoroutineDispatcher()

    lateinit var realm: Realm

    init {
        viewModelScope.launch(realmThreadContext) {
            realm = Realm.getDefaultInstance()
        }
    }

    val users: MutableLiveData<RealmResults<User>> = MutableLiveData()

    suspend fun loadData() {
        withContext(realmThreadContext) {
            users.postValue(realm.where(User::class.java).findAll())
        }
    }

    override fun onCleared() {
        super.onCleared()
        realm.close()
    }
}
class UserActivity : AppCompatActivity() {

    lateinit var viewModel: UserViewModel

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

        viewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        viewModel.users.observe(this, Observer { users ->
            tv_user_names.text = users.joinToString(", ") { it.name }
        })

        lifecycleScope.launch {
            viewModel.loadData()
        }

    }
}

Activity 中我观察MutableLiveData 并对视图的更改做出反应,但它会抛出异常,因为在Realm 中你不能在线程之间传递RealmObject。我想知道你是如何管理的?

我知道有一些解决方法。

一种是在主线程调用Realm.getDefaultInstance,调用findAllAsync得到RealmResults,然后注册一个监听器,观察变化,更新MutableLiveData

另一种解决方案是在后台线程中调用Realm.getDefaultInstance,调用findAll获取RealmResults并调用copyFromRealm,将其传递给MutableLiveData

第一个解决方案可能会更好,因为第二个解决方案会将数据加载到内存中?

但是,如果可能的话,我的目标是在后台保留任何 Realm 内容,请帮助!

【问题讨论】:

    标签: android kotlin realm


    【解决方案1】:

    嗯,你给的这两个解决方案都不适合android框架。

    第一个解决方案:很糟糕,因为 MainThread 不应该知道和处理 Realm 的东西 MainThread 是为布局更改和 android 框架的东西而制作的

    第二种解决方案:很糟糕,因为您将数据库模型传递给您的视图(它不应该知道任何关于数据库或远程数据库的信息)。

    解决方案是: 创建一个名为 UserModel 的对象,然后在您的 ViewModel 中,当您从数据库接收用户时,读取所有这些用户并提取值并为 UserModel 创建一个列表,然后将这些对象返回给 View。

    这是一个很好的分离概念的做法,因为在你的视图中有一个充满领域注释和字段的数据库对象是不好的,然后分离只有视图的重要值并且没有任何数据库注释的对象.这样,您就有了明确的职责分离,并将解决您遇到的这些问题。

    遵循一些 DesignPattern 很重要,RepositoryPattern 是解决一些架构问题的好方法,您可以在此处阅读有关它的信息:https://proandroiddev.com/clean-architecture-data-flow-dependency-rule-615ffdd79e29

    希望对你有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-22
      • 2016-10-10
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      相关资源
      最近更新 更多