我正在创建一个社交媒体应用,并且遵循MVVM
模式
我被DB的observing
数据困住了。据我所知,Dao
方法必须在后台thread
上执行。但是我无法从viewmodel
类实现Repository
。我将粘贴代码,有人可以给我一些帮助吗?
Dao
@Dao
interface FeedDao{
//Post feed item
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(feed:Feed):Long
//Update feed item
@Update(onConflict = OnConflictStrategy.IGNORE)
fun update(feed: Feed):Int
//Get feed from user friend's
@Query("SELECT * from feed")
fun getAllFeed():LiveData<List<Feed>>
}
存储库
class FeedRepository private constructor(private val feedDao: FeedDao) {
companion object {
@Volatile private var instance:FeedRepository? = null
private val apiClient = ApiClient.getApiClient().create(UserClient::class.java)
fun getInstance(feedDao: FeedDao)= instance?: synchronized(this){
instance ?: FeedRepository(feedDao).also { instance=it }
}
}
private fun getFeedResponse() {
//TODO:Check to change parameter values after adding Paging Functionality
val call: Call<List<Feed>> = apiClient.getFeed(20, 0)
call.enqueue(object :Callback<List<Feed>>{
override fun onFailure(call: Call<List<Feed>>?, t: Throwable?) {
Log.e("FeedRepository","Feed Callback Failure")
Timber.d(t?.message)
}
override fun onResponse(call: Call<List<Feed>>?, response: Response<List<Feed>>?) {
if(response!!.isSuccessful){
Timber.i("Successful Response -> Adding to DB")
addResponseTODB(response.body()!!)
}else{
when(response.code()){
400 -> Timber.d("Not Found 400")
500 -> Timber.d("Not logged in or Server broken")
}
}
}
})
}
private fun addResponseTODB(items:List<Feed>){
Timber.d("Response --> DB Started")
object : AsyncTask<List<Feed>,Void,Boolean>(){
override fun doInBackground(vararg params: List<Feed>?): Boolean {
var needsUpdate:Boolean = false
for(item in params[0]!!.iterator()){
var inserted = feedDao.insert(item)
if(inserted.equals(-1)){
var updated = feedDao.update(item)
if(updated > 0){
needsUpdate = true
}
}else{
needsUpdate = true
}
}
return needsUpdate
}
override fun onPostExecute(result: Boolean?) {
if (result!!){
loadFromDB()
}
}
}.execute(items)
}
private fun loadFromDB(){
Timber.d("loadFromDB")
object :AsyncTask<Void,Void,LiveData<List<Feed>>>(){
override fun doInBackground(vararg params: Void?): LiveData<List<Feed>>? {
return feedDao.getAllFeed()
}
override fun onPostExecute(result: LiveData<List<Feed>>?) {
}
}.execute()
}
public fun fetchFeed(){
Timber.d("fetchFeed")
loadFromDB()
getFeedResponse()
}
}
ViewModel
class FeedViewModel private constructor(private val
feedDao:FeedDao):ViewModel(){
// TODO: Implement the ViewModel
private val feedRepository= FeedRepository.getInstance(feedDao)
public val feed = MediatorLiveData<List<Feed>>()
val value = MutableLiveData<Int>()
init {
feed.addSource(feed,feed::setValue)
}
companion object {
private const val NO_FEED = -1
}
fun getFeedLD() = feed
}
答案 0 :(得分:0)
首先,您不需要在Feed
中一个接一个地插入所有Database
个对象。您可以在FeedDao
内创建一个方法来插入List<Feed>
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(feed: List<Feed>):Long
然后,不必在loadFromDB()
方法内调用onPostExecute()
,因为您从fun getAllFeed(): LiveData<List<Feed>>()
来的@FeedDao
方法会返回LiveData
,并且您可以添加{ {1}},并且每次数据库中的数据更改时,Observer
都会被触发。
对于网络/数据库请求,您始终可以使用Observer
https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/src/main/java/com/android/example/github/repository/NetworkBoundResource.kt
希望我有所帮助:)