Данные вставлены, но не могут быть получены с помощью Room - PullRequest
0 голосов
/ 02 февраля 2020

Попытка извлечь данные с сервера с помощью Retrofit и кэшировать их в автономном режиме с использованием базы данных Room.

Проблема Я получил данные с сервера и вставил их в комнату, но мог не заселять это. После оценки выражения список LiveData имеет значение null.

Я уверен, что вставка прошла успешно, так как я прошел через некоторые ответы на StackOverflow, в которых упоминалось, что нужно вернуть список идентификаторов, чтобы выяснить, не было ли insert.

Ниже мой код:

User.kt

@Entity(tableName = "user_table")
data class User(

    @PrimaryKey(autoGenerate = true)
    val id:Long,

    @Json(name = "name")
    val uname:String,
    val username:String,
    val email:String,
    @Embedded
    val address: Address,
    val phone:String,
    val website:String,
    @Embedded
    val company: Company)

data class Address(
    val street:String,
    val suite:String,
    val city:String,
    val zipcode:String,
    @Embedded
    val geo: Geo)

data class Geo(
    val lat:String,
    val lng:String)

data class Company(
    @Json(name = "name")
    val companyName:String,
    val catchPhrase:String,
    val bs:String)

UserDao.kt

@Dao
interface UserDao{

    @Query("select * from user_table")
    fun getUserList():LiveData<List<User>>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insertAll(userList:List<User>):List<Long>
}

UserRepository.kt

class UserRepository(private val userDao: UserDao) {

    val userList: LiveData<List<User>> = userDao.getUserList()

    suspend fun refreshUserList() {
        withContext(Dispatchers.IO) {
            val userList = UserApi.retrofitService.getUserData().await()

            val list = userDao.insertAll(userList)
            Log.e("list","${list.size}")

        }
    }

}

MainActivityViewModel.kt

class MainActivityViewModel(database:UserDao, application: Application) : AndroidViewModel(application){

    private val userRepository = UserRepository(database)
    val usersList = userRepository.userList

    private var viewModelJob = Job()
    private val coroutineScope = CoroutineScope(viewModelJob + Dispatchers.Main)

    init {
        getUsersList()
    }

    private fun getUsersList() {

        coroutineScope.launch {

            try{

                userRepository.refreshUserList()

            }catch (networkError: IOException){
                Toast.makeText(getApplication(),"Failure",Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onCleared() {
        super.onCleared()
        viewModelJob.cancel()
        //Main View Model Destroys
    }
}

UserAdapter.kt

class UserAdapter : RecyclerView.Adapter<UserAdapter.ViewHolder>(){

    var userDetailsList:List<User> = emptyList()
        set(value) {
            field = value
            notifyDataSetChanged()
        }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

        return ViewHolder(UserCellLayoutBinding.inflate(
            LayoutInflater.from(parent.context)
        ))
    }

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        val user = userDetailsList[position]
        holder.bind(user)
    }

    class ViewHolder(private var binding: UserCellLayoutBinding) :
        RecyclerView.ViewHolder(binding.root) {

        fun bind(user: User){
            binding.user = user
            binding.executePendingBindings()
        }
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModelFactory: ViewModelFactory
    private lateinit var viewModel: MainActivityViewModel
    private var adapter:UserAdapter ?= null

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

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        val dataSource = UserRoomDatabase.getInstance(application).userDao
        viewModelFactory = ViewModelFactory(dataSource,application)
        viewModel = ViewModelProviders.of(this,viewModelFactory).get(MainActivityViewModel::class.java)
        binding.lifecycleOwner = this
        binding.mainActivityViewModel = viewModel
        binding.executePendingBindings()
        binding.userListRecyclerView.adapter = adapter

        viewModel.usersList.observe(this, Observer<List<User>> {users ->
            users?.apply {
                adapter?.userDetailsList = users
            }
        })

    }
}

Любая помощь будет принята с благодарностью.

Заранее спасибо.

1 Ответ

0 голосов
/ 03 февраля 2020

Я забыл создать экземпляр адаптера в MainActivity.kt

адаптер = UserAdapter ()

        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        val dataSource = UserRoomDatabase.getInstance(application).userDao
        viewModelFactory = ViewModelFactory(dataSource,application)
        viewModel = ViewModelProviders.of(this,viewModelFactory).get(MainActivityViewModel::class.java)
        binding.lifecycleOwner = this
        binding.mainActivityViewModel = viewModel
        binding.executePendingBindings()

        adapter = UserAdapter()

        binding.userListRecyclerView.adapter = adapter

        viewModel.usersList.observe(this, Observer<List<User>> {users ->
            users?.apply {
                adapter?.userDetailsList = users
            }
        })
...