Android-Kotlin предварительно загружает базу данных номеров

#android #kotlin #android-room

#Android #kotlin #android-комната

Вопрос:

Я использую Kotlin. Я мало что знаю о Java, Kotlin и Android. У меня есть две таблицы: Item и ItemOrderDetails.

Основными файлами в моем проекте являются: ItemDatabase, ItemDao, ItemOrderDetailsDao, Item, ItemOrderDetails, ItemRepository и ItemViewModel.

  1. Сущность (Item amp; ItemOrderDetails).
  2. DAO (ItemDao и ItemOrderDetailsDao).
  3. База данных (ItemDatabase).
  4. Репозиторий (ItemRepository).
  5. ViewModel (ItemViewModel).

Сначала необходимо проверить, существуют ли данные или нет. Это должно работать следующим образом:

Если данных не существует, предварительно загрузите все данные в две таблицы.

Если данные уже существуют в таблицах, обновите данные, то есть объедините данные, которые будут предварительно загружены, и данные, которые уже существуют. Если в этом случае есть копии одних и тех же данных, перезапишите данные.

Пожалуйста, скажите мне, как внести изменения в ItemDatabase.kt, чтобы реализовать это.

Войти

 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.itemapp, PID: 24878
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.itemapp/com.example.itemapp.MainActivity}: java.lang.RuntimeException: Cannot create an instance of class com.example.itemapp.viewmodel.ItemViewModel
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2895)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1616)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:176)
        at android.app.ActivityThread.main(ActivityThread.java:6651)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824)
     Caused by: java.lang.RuntimeException: Cannot create an instance of class com.example.itemapp.viewmodel.ItemViewModel
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:275)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185)
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150)
        at com.example.itemapp.fragments.list.ListFragment.onCreateView(ListFragment.kt:43)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2699)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2637)
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589)
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2723)
        at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:346)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1200)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2637)
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589)
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247)
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541)
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1335)
        at android.app.Activity.performStart(Activity.java:7108)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2895) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1616) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:176) 
        at android.app.ActivityThread.main(ActivityThread.java:6651) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824) 
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Constructor.newInstance0(Native Method)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
        at androidx.lifecycle.ViewModelProvider$AndroidViewModelFactory.create(ViewModelProvider.java:267)
        at androidx.lifecycle.SavedStateViewModelFactory.create(SavedStateViewModelFactory.java:106) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:185) 
        at androidx.lifecycle.ViewModelProvider.get(ViewModelProvider.java:150) 
        at com.example.itemapp.fragments.list.ListFragment.onCreateView(ListFragment.kt:43) 
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2699) 
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1199) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368) 
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509) 
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2637) 
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589) 
        at androidx.fragment.app.Fragment.performActivityCreated(Fragment.java:2723) 
        at androidx.fragment.app.FragmentStateManager.activityCreated(FragmentStateManager.java:346) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1200) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1368) 
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1446) 
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1509) 
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2637) 
        at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2589) 
        at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:247) 
        at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:541) 
        at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:210) 
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1335) 
        at android.app.Activity.performStart(Activity.java:7108) 
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780) 
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2895) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1616) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:176) 
        at android.app.ActivityThread.main(ActivityThread.java:6651) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:824) 
     Caused by: java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
        at androidx.room.RoomDatabase.assertNotMainThread(RoomDatabase.java:267)
        at androidx.room.RoomDatabase.query(RoomDatabase.java:323)
        at androidx.room.util.DBUtil.query(DBUtil.java:83)
        at com.example.itemapp.data.ItemOrderDetailsDao_Impl.getAllItems(ItemOrderDetailsDao_Impl.java:109)
        at com.example.itemapp.repository.ItemRepository.<init>(ItemRepository.kt:15)
        at com.example.itemapp.viewmodel.ItemViewModel.<init>(ItemViewModel.kt:24)
            ... 38 more

 

ListFragment.kt

 class ListFragment : Fragment(), RecyclerView_1_Adapter.OnItemClickListener1 {

    private lateinit var mItemViewModel: ItemViewModel
    private lateinit var nItemViewModel: ItemViewModel
    var itemList = mutableListOf<Item>()
    mItemViewModel.addItems(DataFragment.item_data)   // Error: Expecting member declaration.

    private lateinit var recyclerView1_adapter: RecyclerView_1_Adapter
    lateinit var recyclerView1 : RecyclerView

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_list, container, false)

        recyclerView1_adapter = RecyclerView_1_Adapter(itemList, this)
        recyclerView1 = view.recyclerview1
        recyclerView1.layoutManager = LinearLayoutManager(requireContext())
        recyclerView1.adapter = recyclerView1_adapter

        // ItemViewModel
        mItemViewModel = ViewModelProvider(this).get(ItemViewModel::class.java)
        nItemViewModel.addItems(DataFragment.item_data)
        nItemViewModel.insertItems(DataFragment.item_order_details_data)

        mItemViewModel.readAllData.observe(viewLifecycleOwner, Observer { item ->
            recyclerView1_adapter.setData(item)
        })
               
        return view
    }
          
}
 

RecyclerView_1_Adapter.kt

 class RecyclerView_1_Adapter (
    var itemList: MutableList<Item>, // = mutableListOf<Item>()
    val listener1: OnItemClickListener1
) : RecyclerView.Adapter<RecyclerView_1_Adapter.RecyclerView_1_DataViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView_1_DataViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.recyview1_row, parent, false)
        return RecyclerView_1_DataViewHolder(view)
    }

    override fun getItemCount(): Int {
        return itemList.size
    }

    override fun onBindViewHolder(holder: RecyclerView_1_DataViewHolder, position: Int) {
        val currentItem = itemList[position]
        holder.itemView.apply {
            firstName_list.text = currentItem.firstName
            lastName_list.text = currentItem.lastName
        }
    }

    inner class RecyclerView_1_DataViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
        View.OnClickListener {

        init {
            itemView.setOnClickListener(this)
        }

        override fun onClick(v: View?) {
            val position = adapterPosition
            val currentItem2 = itemList[position]
            if (position != RecyclerView.NO_POSITION) {
                listener1.onItemClick1(position, currentItem2)
            }
        }
    }

    interface OnItemClickListener1 {
        fun onItemClick1(position: Int, currentItem1: Item)
    }

    fun setData(item: MutableList<Item>){
        this.itemList = item
        notifyDataSetChanged()
    }

}
 

ItemDao.kt (updated)

 @Dao
interface ItemDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun addItem(item: Item)
//    suspend fun insertItems(item: Item)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun addItems(items: List<Item>)

    @Update
    suspend fun updateItem(item: Item)

    @Delete
    suspend fun deleteItem(item: Item)

    @Query("DELETE FROM item_table")
    suspend fun deleteAllItems()

    @Query("SELECT * FROM item_table ORDER BY id ASC")
    fun readAllData(): LiveData<MutableList<Item>>

}
 

ItemOrderDetailsDao.kt (updated)

 @Dao
interface ItemOrderDetailsDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertItem(items: ItemOrderDetails)

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertItems(item: List<ItemOrderDetails>)

    @Query("SELECT * FROM item_order_details_table ORDER BY id ASC")
    fun getAllItems(): MutableList<ItemOrderDetails>

}
 

ItemRepository.kt (updated)

 class ItemRepository(
    private val itemDao: ItemDao,
    private val itemOrderDetailsDao: ItemOrderDetailsDao
) {

    val readAllData: LiveData<MutableList<Item>> = itemDao.readAllData()
    val getAllItems: MutableList<ItemOrderDetails> = itemOrderDetailsDao.getAllItems()
    /*suspend fun readAllData(user: Item){
        itemDao.readAllData(LiveData<List<Item>>)
    }*/

    suspend fun addItem(item: Item){
        itemDao.addItem(item)
    }

    suspend fun insertItem(item: ItemOrderDetails) {
        itemOrderDetailsDao.insertItem(item)
    }

    suspend fun addItems(items: List<Item>){
        itemDao.addItems(items)
    }

    suspend fun insertItems(items: List<ItemOrderDetails>){
        itemOrderDetailsDao.insertItems(items)
    }

    suspend fun updateItem(item: Item){
        itemDao.updateItem(item)
    }

    suspend fun deleteItem(item: Item){
        itemDao.deleteItem(item)
    }

    suspend fun deleteAllItems(){
        itemDao.deleteAllItems()
    }

}
 

ItemViewModel.kt (updated)

 class ItemViewModel(application: Application): AndroidViewModel(application) {

    val readAllData: LiveData<MutableList<Item>>
    val getAllItems: MutableList<ItemOrderDetails>
    private val repository: ItemRepository

    init {
        val itemDao = App.db.itemDao()
        val itemOrderDetailsDao = App.db.itemOrderDetailsDao()
//        val itemDao = ItemDatabase.getDatabase(application).userDao()

        repository = ItemRepository(itemDao, itemOrderDetailsDao)
        readAllData = repository.readAllData
        getAllItems = repository.getAllItems
    }

    fun addItem(item: Item){
        viewModelScope.launch(Dispatchers.IO) {
            repository.addItem(item)
        }
    }

    fun insertItem(item: ItemOrderDetails) {
        viewModelScope.launch(Dispatchers.IO) {
            repository.insertItem(item)
        }
    }

    fun addItems(items: List<Item>){
        viewModelScope.launch(Dispatchers.IO) {
            repository.addItems(items)
        }
    }

    fun insertItems(items: List<ItemOrderDetails>){
        viewModelScope.launch(Dispatchers.IO) {
            repository.insertItems(items)
        }
    }

    fun updateItem(item: Item){
        viewModelScope.launch(Dispatchers.IO) {
            repository.updateItem(item)
        }
    }

    fun deleteItem(item: Item){
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteItem(item)
        }
    }

    fun deleteAllItems(){
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteAllItems()
        }
    }
    
    App.db.itemDao().addItemsFromFragment(DataFragment.item_data)   // Expecting member declaration
    App.db.itemOrderDetailsDao().insertItemsFromFragment(DataFragment.item_order_details_data)  // Expecting member declaration
   
}
 

DataFragment.kt (updated)

 class DataFragment {

    companion object Data{
        var item_order : Int = 0
        var item_order_alert : Int = 0
        var selectedItems1 = arrayOf<Int>(0)

        var item_details_list = mutableListOf<ItemDetails>()
        
        val item_data = listOf(
            Item(0, "first_name_1", "last_name_1", "item_value_a_1"),
            Item(0, "first_name_2", "last_name_2", "item_value_a_2"),
            Item(0, "first_name_3", "last_name_3", "item_value_a_3")
        )

        val item_order_details_data = listOf(
            ItemOrderDetails(0, "item_group_1", "item_name_1", "item-value_b_1", "item_base_1", "item_up_1"),
            ItemOrderDetails(0, "item_group_2", "item_name_2", "item-value_b_2", "item_base_2", "item_up_2"),
            ItemOrderDetails(0, "item_group_3", "item_name_3", "item-value_b_3", "item_base_3", "item_up_3")
        )

        fun addItemsFromFragment(items: List<Item>){
            viewModel.addItems(items)
        }

        fun insertItemsFromFragment(items: List<ItemOrderDetails>){
            viewModel.insertItems(items)
        }

    }

}
 

MainActivity.kt (updated)

 package com.example.itemapp

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.setupActionBarWithNavController
import com.example.itemapp.data.App
import com.example.itemapp.fragments.add.DataFragment

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

        setupActionBarWithNavController(findNavController(R.id.fragment))

        App.db.itemDao().addItemsFromFragment(DataFragment.item_data)
        App.db.itemOrderDetailsDao().insertItemsFromFragment(DataFragment.item_order_details_data)
        // Error - Unresolved reference: addItemsFromFragment
        // Error - Unresolved reference: insertItemsFromFragment        
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.fragment)
        return navController.navigateUp() || super.onSupportNavigateUp()
    }
}
 

ItemDatabase.kt (updated)

 package com.example.itemapp.data

import androidx.room.Database
import androidx.room.RoomDatabase
import com.example.itemapp.model.Item
import com.example.itemapp.model.ItemOrderDetails

@Database(
    entities = [
        Item::class,
        ItemOrderDetails::class
    ], version = 1, exportSchema = false)
abstract class ItemDatabase : RoomDatabase() {

//    abstract fun userDao(): ItemDao

    abstract fun getItemDao(): ItemDao
    abstract fun getItemDetailsDao(): ItemOrderDetailsDao

        /*companion object {
            @Volatile
            private var INSTANCE: ItemDatabase? = null

            fun getDatabase(context: Context): ItemDatabase {
                val tempInstance = INSTANCE
                if (tempInstance != null) {
                    return tempInstance
                }
                synchronized(this) {
                    val instance = Room.databaseBuilder(
                        context.applicationContext,
                        ItemDatabase::class.java,
                        "item_database"
                    ).build()
                    INSTANCE = instance
                    return instance
                }
            }
        }*/
}
 

DbRepository.kt (updated)

 package com.example.itemapp.data

import android.content.Context
import androidx.room.Room

    // Adding a new class to access DB.
class DbRepository (private val database: ItemDatabase) {

    companion object {
        private var instance: DbRepository? = null

        fun getInstance(context: Context): DbRepository {
            return instance ?: synchronized(this) {
                instance ?: DbRepository(initializeDb(context)).also { instance = it }
            }
        }

        private fun initializeDb(context: Context): ItemDatabase {
            return Room.databaseBuilder(
                context,
                ItemDatabase::class.java, "ItemDb"
            ).build()
        }
    }

    fun itemDao():ItemDao = database. getItemDao()

    fun itemDetailsDao():ItemOrderDetailsDao = database.getItemDetailsDao()
}
 

App.kt (updated)

 package com.example.itemapp.data

import android.app.Application

    //  Creating a single instance of the DbRepository throughout the app. It is done in App class.
class App : Application() {

    companion object {
        lateinit var db: DbRepository
    }

    override fun onCreate() {
        super.onCreate()
        db = DbRepository.getInstance(applicationContext)
    }
}

    /*You can access the App class from any class of that module like this:
    App.db.itemDao().insertItems(data)
    Note: Remember to call these DB functions on a background thread.*/
 

AndroidManifest.xml (updated)

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.itemapp">

    <application
        android:name=".App"   // Error.

        /* Class referenced in the manifest, com.example.itemapp.App, was not 
           found in the project or the libraries. Unresolved class 'App' */ 

        android:allowBackup="true"   
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name="com.example.itemapp.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
 

Item.kt

 package com.example.itemapp.model

import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize

@Parcelize
@Entity(tableName = "item_table")
data class Item(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val firstName: String,
    val lastName: String,
    val item_value_a: String = "0"
    ): Parcelable

 

ItemOrderDetails.kt

 package com.example.itemapp.model

import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import kotlinx.android.parcel.Parcelize

@Parcelize
@Entity(tableName = "item_order_details_table")
data class ItemOrderDetails(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    val item_group: String,
    val item_name: String,
    val item_value_b: String = "0",
    val item_base: String,
    val item_up: String
): Parcelable
 

Данные для таблиц следующие…

Данные Item.kt

 val item_data = listOf(
            Item("first_name_1", "last_name_1", "item_value_a_1"),
            Item("first_name_2", "last_name_2", "item_value_a_2"),
            Item("first_name_3", "last_name_3", "item_value_a_3")
)
 

Данные ItemOrderDetails.kt

 val item_order_details_data = listOf(
            ItemOrderDetails("item_group_1", "item_name_1", "item-value_b_1", "item_base_1", "item_up_1"),
            ItemOrderDetails("item_group_2", "item_name_2", "item-value_b_2", "item_base_2", "item_up_2"),
            ItemOrderDetails("item_group_3", "item_name_3", "item-value_b_3", "item_base_3", "item_up_3")
)
 

Комментарии:

1. Вы спрашиваете об операциях с комнатами?

2. Я просто хочу, чтобы кто-нибудь дал мне коды для моего файла ItemDatabase.kt, то есть коды в соответствии с моим вопросом. Я много читал об этом. Мне нужны правильные коды для реализации этих функций, описанных в моем вопросе.

3. Для предварительной загрузки данных необходимы некоторые дополнительные коды для файла ItemDatabase.kt. У меня есть две таблицы. Я не знаю, как это сделать.

Ответ №1:

Выполните следующие действия:

  1. Создайте еще Dao один подобный ItemDao для ItemOrderDetails таблицы.
  2. Добавьте следующие методы в оба Dao :
     @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertItems(item: List<YourModelName>)
    
    @Query("SELECT * FROM YourModelName")
    suspend fun getAllItems(): List<YourModelName>
     

Эти функции помогут вам получать элементы из DB каталога и вставлять в него элементы. OnConflictStrategy.REPLACE проверит, есть ли элемент, уже присутствующий в таблице с тем же первичным ключом. Если да, то он заменит его новым элементом.

  1. Измените свой ItemDatabase класс на этот:
     @Database(entities = [
        Item::class,
        ItemOrderDetails::class], version = 1)
    abstract class ItemDatabase: RoomDatabase() {
    
    abstract fun getItemDao(): ItemDao
    abstract fun getItemDetailsDao(): ItemOrderDetailsDao
     

    }

  2. Добавьте новый класс в access DB .
     class DbRepository (private val database: ItemDatabase) {
    
    companion object {
        private var instance: DbRepository? = null
    
        fun getInstance(context: Context): DbRepository {
            return instance ?: synchronized(this) {
                instance ?: DbRepository(initializeDb(context)).also { instance = it }
            }
        }
    
        private fun initializeDb(context: Context): ItemDatabase {
            return Room.databaseBuilder(
                context,
                ItemDatabase::class.java, "ItemDb"
            ).build()
        }
    }
    
    fun itemDao():ItemDao = database. getItemDao()
    
    fun itemDetailsDao():ItemOrderDetailsDao = database.getItemDetailsDao()
     

    }

  3. Создайте один экземпляр DbRepository всего приложения, и вы можете сделать это в классе приложения.
     class App: Application() {
    
    companion object {
        lateinit var db: DbRepository
    }
    
    override fun onCreate() {
        super.onCreate()
        db = DbRepository.getInstance(applicationContext)
    }
     

    }

  4. Вы можете получить доступ к App классу из любого класса этого модуля следующим образом:

    App.db.itemDao().insertItems(data)

Примечание: Не забудьте вызвать эти DB функции в фоновом потоке.


Редактировать 1.0

Следуйте инструкциям, чтобы вызвать DB функции в фоновом потоке.

  1. Добавьте implementation "androidx.fragment:fragment-ktx:1.2.5" зависимость в свой app's gradle file .
  2. Добавьте private val viewModel:ItemViewModel by viewModels() в свой DataFragment .
  3. Добавьте новую функцию в свой ItemRepository класс.
 
suspend fun addItems(items: List<Item>){
        itemDao.insertItems(item)
    }

 
  1. Добавьте новую функцию в свой ItemViewModel класс.
 
fun addItems(items: List<Item>){
        viewModelScope.launch {
            repository.addItems(items)
        }
    }

 
  1. Вызовите DB операцию, используя функции, которые находятся в вашем ItemViewModel классе, из вашего DataFragment класса.
 
fun addItemsFromFragment(items: List<Item>){
        viewModel.addItems(items)
    }

 

Редактировать 1.1

Добавьте эту функцию в свой ItemDao и сделайте то же самое для ItemDetailsDao .

 
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertItems(item: List<Item>)

 

Редактировать 1.2

Добавьте эту функцию в свой ItemViewModel .

 
fun addItems(items:List<Item>) {
   viewModelScope.launch {
       App.db.itemDao().insertItems(items)
   }
}

 

И вызовите эту функцию из вашего Fragment .

 
class DataFragment {

    companion object Data{
        var item_order : Int = 0
        var item_order_alert : Int = 0
        var selectedItems1 = arrayOf<Int>(0)

        var item_details_list = mutableListOf<ItemDetails>()
        
        val item_data = listOf(
            Item(0, "first_name_1", "last_name_1", "item_value_a_1"),
            Item(0, "first_name_2", "last_name_2", "item_value_a_2"),
            Item(0, "first_name_3", "last_name_3", "item_value_a_3")
        )

        val item_order_details_data = listOf(
            ItemOrderDetails(0, "item_group_1", "item_name_1", "item-value_b_1", "item_base_1", "item_up_1"),
            ItemOrderDetails(0, "item_group_2", "item_name_2", "item-value_b_2", "item_base_2", "item_up_2"),
            ItemOrderDetails(0, "item_group_3", "item_name_3", "item-value_b_3", "item_base_3", "item_up_3")
        )

        fun addItemsFromFragment(items: List<Item>){
            viewModel.addItems(items) // This will add your items. Remove lines which are causing error from your viewmodel.
        }

    }

}

 

Комментарии:

1. Я думаю, что я делаю ошибку в реализации вашего ответа. У меня тоже есть некоторые сомнения.

2. Я добавил ItemRepository, ItemOrderDetailsDao и ItemDatabase после применения вашего ответа. Пожалуйста, попробуйте использовать те же переменные, которые я использовал, так как я новичок в Kotlin, Room и т. Д. У меня уже есть рабочий проект, в который я пытаюсь включить ваши коды, чтобы я мог его изменить.

3. Была функция getDatabase(), которая использовалась в ItemViewModel и ItemDatabase. Теперь он показывает ошибку. Я хочу включить ваши коды в свой проект. Я могу понять ваши коды, только если они используют имена переменных в моем проекте.

4. Мне нужно будет изучить ваш код, чтобы помочь вам с этим. Если возможно, поделитесь кодом, в котором вы столкнулись с ошибками.

5. Основными файлами в моем проекте являются: ItemDatabase, ItemDao, ItemOrderDetailsDao, Item, ItemOrderDetails, ItemRepository и ItemViewModel.