Попытка извлечь данные с сервера с помощью 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
}
})
}
}
Любая помощь будет принята с благодарностью.
Заранее спасибо.