如何正确初始化 Room (AndroidViewModel)?

问题描述 投票:0回答:1

我正在使用带有

AndroidViewModel
(无工厂)的房间数据库

class RoomModel(app: Application) : AndroidViewModel(app) {
        // ....
}

我不确定如何正确初始化它,也不知道我是否可以对整个应用程序使用一次性初始化。

我有两种处理初始化的方法,似乎工作正常:

onViewCreated()
中初始化:

...
private lateinit var database: RoomModel
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        ...
        database = ViewModelProvider(this)[RoomModel::class.java]
        ...
}

通过

activityViewModels()
初始化:

...
private val mData: RoomModel by activityViewModels()
...

两者似乎都有效,但不确定哪一个永远不会在某个时候导致应用程序崩溃。

另外,我想知道,使用我的

RoomModel
的一个共享引用变量是否是一种好的做法,该变量在由其他片段使用的基本片段中声明和初始化,如下所示:

class BaseFragment : Fragment() {
        ...
        lateinit var database: RoomModel
        // Or
        val database: RoomModel by activityViewModels()
        ...
        
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
                ...
                database = ViewModelProvider(this)[RoomModel::class.java]
                ...
        }
}

BaseFragment()
扩展的一些其他片段如下:

class FragmentA : BaseFragment() {
        ...
            
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
            ...
            // use the reference variable database to observe or add or edit data
        }
} 

class FragmentB : BaseFragment() {
        ...
            
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
            ...
            // use the reference database to observe or add or edit data

        }
} 

等等...

通过这种方式,我只需初始化房间一次并使用它,而无需在我需要访问的每个片段中重新初始化。这是一个好主意还是我需要在我需要访问的每个片段中使用单独的声明和初始化

RoomModel

android android-room android-viewmodel
1个回答
2
投票

您的房间数据库实例应该是单例。实例的生存时间应与应用程序本身一样长。每次需要使用它时都初始化它的成本很高。您应该在应用程序中初始化房间数据库,并且每个需要房间数据库实例的

ViewModel
将从应用程序中获取它作为依赖项。或者您可以提供房间数据库作为
ViewModel
的依赖项,但随后您需要为您的
ViewModel
创建一个工厂。您还可以使用依赖注入库来为您管理它,但一开始它可能会让人不知所措。

在不使用任何依赖注入库的情况下,您可以看到下面的示例。

覆盖

Application
,并且不要忘记在
AndroidManifest.xml
文件中声明它。

AndroidApp.kt

class AndroidApp : Application() {

    lateinit var myRoomDatabase: MyRoomDatabase

    override fun onCreate() {
        super.onCreate()
        myRoomDatabase = Room
            .databaseBuilder(applicationContext, MyRoomDatabase::class.java, "my-room-database")
            .build()
    }
}

AndroidManifest.xml

...
<application
        android:name=".AndroidApp"
...
>
...

当您扩展

AndroidViewModel
时,您将
Application
实例作为依赖项。将其投射到
AndroidApp
,现在您可以获得
myRoomDatabase

MainViewModel.kt

class MainViewModel(app:Application) : AndroidViewModel(app) {
    private val myRoomDatabase = (app as AndroidApp).myRoomDatabase
    ...
}

FragmentAViewModel.kt

class FragmentAViewModel(app:Application) : AndroidViewModel(app) {
    private val myRoomDatabase = (app as AndroidApp).myRoomDatabase
    ...
}

FragmentBViewModel.kt

class FragmentBViewModel(app:Application) : AndroidViewModel(app) {
    private val myRoomDatabase = (app as AndroidApp).myRoomDatabase
    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.