1

私はAndroidプロジェクトでRoom + LiveDataを使用しています。 Google Blueprintsに続いて、私は自分のアプリケーションのデータレイヤーを実装しました。アイテムをIDで取得

これは私のダオがどのように見えるかです:私は私のEventRepositoryからそれを呼んでいる

@Query("SELECT * FROM events WHERE id=:arg0") 
    fun loadSingle(id: String): LiveData<Event> 

NetworkManagerのクラスは( hereから "とら" されている)されて
fun loadSingle(eventId: String): LiveData<RequestReader<Event>> { 
     return object: NetworkManager<Event, Event>(appExecutors!!) { 

      override fun loadLocal(): LiveData<Event> { 
       val item = eventLocal!!.loadSingle("Title 1") 
       Crashlytics.log(Log.VERBOSE, TAG, "loadFromServer::loadLocal=$item") 
       return item 
      } 

      override fun isUpdateForced(data: Event?): Boolean { 
       Crashlytics.log(Log.VERBOSE, TAG, "loadFromServer::isUpdateForced") 
       return data == null || requestTimeout.isAllowed(UNDEFINED_KEY.toString()) 
      } 

      override fun makeRequest(): LiveData<ApiResponse<Event>> { 
       Crashlytics.log(Log.VERBOSE, TAG, "loadFromServer::makeRequest") 
       return Database.createService(EventRemote::class.java).load(eventId) 
      } 

      override fun onSuccess(item: Event) { 
       eventLocal?.save(item) 
      } 

      override fun onFail() { 
       Crashlytics.log(Log.VERBOSE, TAG, "loadFromServer::onFail") 
       requestTimeout.reset(UNDEFINED_KEY.toString()) 
      } 

     }.liveData 
    } 

abstract class NetworkManager<ResultType, RequestType> @MainThread constructor(val appExecutors: AppExecutors) { 

     companion object { 
      private val TAG = "TAG_NETWORK_MANAGER" 
     } 

     val liveData: MediatorLiveData<RequestReader<ResultType>> = MediatorLiveData() 

     init { 
      liveData.value = RequestReader.loading(null) 
      val localSource: LiveData<ResultType> = loadLocal() 
      Log.d(TAG, "before add::localSource=${localSource.value}") 
      liveData.addSource(localSource, { data -> 
       Log.d(TAG, "data=$data") 
       liveData.removeSource(localSource) 
       if (isUpdateForced(data)) { 
        loadRemote(localSource) 
       } else { 
        liveData.addSource(localSource, { reusedData -> liveData.value = RequestReader.success(reusedData)}) 
       } 
      }) 
     } 

     private fun loadRemote(localSource: LiveData<ResultType>) { 
      val remoteSource = makeRequest() 
      liveData.addSource(localSource, { 
       liveData.value = RequestReader.success(it) 
      }) 
      liveData.addSource(remoteSource) { response -> 
       liveData.removeSource(localSource) 
       liveData.removeSource(remoteSource) 
       if (response!!.isSuccessful) { 
        appExecutors.diskIO.execute { 
         onSuccess(processResponse(response)) 
         appExecutors.mainThread.execute { 
          liveData.addSource(localSource, { 
           liveData.value = RequestReader.success(it) 
          }) 
         } 
        } 
       } else { 
        onFail() 
        liveData.addSource(localSource, { 
         liveData.value = RequestReader.error("Error: ${response.errorMessage}", it) 
        }) 
       } 
      } 

     } 

     @MainThread 
     protected abstract fun loadLocal(): LiveData<ResultType> 

     @MainThread 
     protected abstract fun isUpdateForced(data: ResultType?): Boolean 

     @MainThread 
     protected abstract fun makeRequest(): LiveData<ApiResponse<RequestType>> 

     @WorkerThread 
     protected abstract fun onSuccess(item: RequestType) 

     @MainThread 
     protected abstract fun onFail() 

     @WorkerThread 
     protected fun processResponse(response: ApiResponse<RequestType>): RequestType { 
     return response.body!! 
    } 
} 

open class EventSingleViewModel: ViewModel(), RepositoryComponent.Injectable { 

    companion object { 
     private val TAG = "TAG_EVENT_SINGLE_VIEW_MODEL" 
    } 

    @Inject lateinit var eventRepository: EventRepository 

    var eventSingle: LiveData<RequestReader<Event>>? = null 

    override fun inject(repositoryComponent: RepositoryComponent) { 
     repositoryComponent.inject(this) 
     eventSingle = MutableLiveData<RequestReader<Event>>() 
    } 

    fun load(eventId: String) { 
     Crashlytics.log(Log.VERBOSE, TAG, "starts to loadList::eventId=$eventId") 
     eventSingle = eventRepository.loadSingle(eventId) 
    } 

} 

問題:OのViewModelで私のLiveDataを取得します。 私は上で説明したのと同じ方法でイベントのリストを取得しています(このイベントはすでにデータベースにあります)が機能しません。私はlocalSource.valueがnullであることを知りました(NetworkManager)。たぶん私のクエリが悪いですか..何か他の。

ありがとうございます。

答えて

1

DAOの実装をもう一度確認します。引数は、関数パラメータと注釈argの両方で同じである必要があります。

変更この:

@Query("SELECT * FROM events WHERE id=:arg0") 
    fun loadSingle(id: String): LiveData<Event> 

へ:

@Query("SELECT * FROM events WHERE id = :id ") 
     fun loadSingle(id: String): LiveData<Event> 
関連する問題