大佬教程收集整理的这篇文章主要介绍了我的第一个观察者正确调用,但在 kotlin android 中将数据插入房间数据库后没有调用另一个观察者 建议/解决方案说明,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在应用程序中,我从网络和观察者更改方法中获取数据,将该数据插入到本地数据库中。没关系。但是插入到数据库后,我的第二个观察者没有被调用,所以我的 UI 不会更新。
@H_699_5@manActivity.class
class MainActivity : AppCompatActivity() {
private lateinit var viewmodel: Mainviewmodel
private lateinit var adapter: MainAdapter
overrIDe fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceStatE)
setContentVIEw(layout.activity_main)
setupviewmodel()
setupUI()
setupObservers()
setupObservers2()
}
private fun setupviewmodel() {
viewmodel = viewmodelProvIDers.of(
this,viewmodelFactory(APIHelper(RetrofitBuilder.APIservicE))
).get(Mainviewmodel::class.java)
}
private fun setupUI() {
recyclerVIEw.layoutManager = linearlayoutmanager(this)
adapter = MainAdapter(arraylistof())
recyclerVIEw.addItemdecoration(
divIDerItemdecoration(
recyclerVIEw.context,(recyclerVIEw.layoutManager as linearlayoutmanager).orIEntation
)
)
recyclerVIEw.adapter = adapter
}
private fun setupObservers() {
viewmodel.getUsers().observe(this,Observer {
//viewmodel.getUserFromWeb()
it?.let { resource ->
when (resource.status) {
succesS -> {
Log.d("MYLOG","MyAPIChange success")
recyclerVIEw.visibility = VIEw.VISIBLE
progressbar.visibility = VIEw.GONE
resource.data?.let {
users -> viewmodel.setUserListToDB(this,users)
//sleep(1000)
}
}
ERROR -> {
recyclerVIEw.visibility = VIEw.VISIBLE
progressbar.visibility = VIEw.GONE
Log.d("MYLOG","MyAPIChange error")
Toast.makeText(this,it.message,Toast.LENGTH_LONG).show()
}
LOADING -> {
Log.d("MYLOG","MyAPIChange loading")
progressbar.visibility = VIEw.VISIBLE
recyclerVIEw.visibility = VIEw.GONE
}
}
}
})
}
private fun setupObservers2() {
viewmodel.getUserFromDB(this).observe(this,Observer {
users -> retrIEveList(users)
Log.d("MYLOG","..MyDBChange")
})
}
private fun retrIEveList(users: List<User>) {
adapter.apply {
addUsers(users)
notifyDataSetChanged()
}
}
}
class Mainviewmodel(private val mainRepository: MainRepository) : viewmodel() {
//lateinit var tempuser : mutablelivedata<List<User>>
fun getUsers() = liveData(dispatchers.IO) {
emit(resource.loading(data = null))
try {
emit(resource.success(data = mainRepository.getUsers()))
} catch (exception: Exception) {
emit(resource.error(data = null,message = exception.message ?: "Error Occurred!"))
}
//emit(mainRepository.getUsers()) //direct call
}
fun getUserFromDB(context: Context) = liveData(dispatchers.IO) {
emit(mainRepository.getUserList(context))
}
fun setUserListToDB(context: Context,userList: List<User>) {
/*GlobalScope.launch {
mainRepository.setUserList(context,userList)
}*/
CoroutInescope(dispatchers.IO).launch {
mainRepository.setUserList(context,userList)
}
}
}
@H_699_5@myRepository.class
class MainRepository(private val APIHelper: APIHelper) {
suspend fun getUsers() = APIHelper.getUsers() // get from web
companion object {
var myDatabase: MyDatabase? = null
lateinit var userList: List<User>
fun initializeDB(context: Context): MyDatabase {
return MyDatabase.getDataseClIEnt(context)
}
/*fun insertData(context: Context,username: String,password: String) {
myDatabase = initializeDB(context)
CoroutInescope(dispatchers.IO).launch {
val loginDetails = User(username,password)
myDatabase!!.myDao().InsertData(loginDetails)
}
}*/
}
//fun getUserList(context: Context,username: String) : liveData<LogintableModel>? {
suspend fun getUserList(context: Context) : List<User> {
myDatabase = initializeDB(context)
userList = myDatabase!!.myDao().getUserList()
Log.d("MYLOG=","DBREAD"+userList.size.toString())
return userList
}
fun setUserList(context: Context,userList: List<User>){
myDatabase = initializeDB(context)
/*CoroutInescope(dispatchers.IO).launch {
myDatabase!!.myDao().InsertAllUser(userList)
Log.d("MYLOG","MyDBInserted")
}*/
myDatabase!!.myDao().InsertAllUser(userList)
Log.d("MYLOG","MyDBInserted")
/*val thread = Thread {
myDatabase!!.myDao().InsertAllUser(userList)
}
Log.d("MYLOG","MyDBInserted")
thread.start()*/
}
}
DAO 类
@Dao
interface DAOAccess {
@Insert(onConflict = OnConflictStrategy.replaCE)
fun InsertAllUser(userList: List<User>)
// @query("SELECT * FROM User WHERE Username =:username")
// fun getLoginDetails(username: String?) : liveData<LogintableModel>
@query("SELECT * FROM User")
suspend fun getUserList() : List<User>
}
RetrofitBuilder
object RetrofitBuilder {
private const val BASE_URL = "https://5e510330f2c0d300147c034c.mockAPI.io/"
private fun getRetrofit(): Retrofit {
return Retrofit.builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
val APIservice: APIservice = getRetrofit().create(APIservice::class.java)
}
请你知道我在这里做错了什么以及为什么在插入到 db 后没有调用第二个观察者
实际上它是在屏幕启动时调用的,但当时没有插入数据,因此列表大小为 0,插入数据后,此方法不会再次调用。但是一旦我关闭应用程序并再次启动,数据将在启动时显示 bcoz,此方法调用和数据得到
我没有足够的声望来commet,因此我只是在这个答案中提出了一个建议:
Room 支持开箱即用的 LiveData。所以在你的 DAO 中你可以改变
suspend fun getUserList() : List<User>
到
suspend fun getUserList() : LiveData<List<User>>
然后在您的存储库中调整为
suspend fun getUserList(context: Context) : LiveData<List<User>> {
myDatabase = initializeDB(context)
userList = myDatabase!!.myDao().getUserList()
Log.d("MYLOG=","DBREAD"+userList.value.size.toString())
return userList
}
在视图模型中
fun getUserFromDB(context: Context) = mainRepository.getUserList(context))
通过这些调整,我认为它应该会奏效。
您在这里使用了 liveData 协程构建器
fun getUserFromDB(context: Context) = liveData(Dispatchers.IO) {
emit(mainRepository.getUserList(context))
}
据我所知,这个构建器是为了执行一些异步/挂起任务,一旦这个任务完成,你创建的 liveData 就会发出结果。这意味着您只有一次收到用户列表的状态,然后将列表发送给观察者一次,然后这个 liveData 就完成了。它不会一直观察数据库中列表的变化。
这就是为什么它非常适合观察 API 调用(您想等到调用完成并发出一次响应),而不是观察 DB 状态(您想观察用户列表中的用户列表) DB 并在列表更改时向观察者发出更改)
以上是大佬教程为你收集整理的我的第一个观察者正确调用,但在 kotlin android 中将数据插入房间数据库后没有调用另一个观察者 建议/解决方案说明全部内容,希望文章能够帮你解决我的第一个观察者正确调用,但在 kotlin android 中将数据插入房间数据库后没有调用另一个观察者 建议/解决方案说明所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。