1

Android 프로젝트에서 Room + LiveData를 사용하고 있습니다. Google Blueprints에 따라 애플리케이션의 데이터 레이어를 구현했습니다. 내 EventRepository에서 호출하고 있습니다ID로 항목 가져 오기

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

:처럼 내 다오 모양을

이입니다

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 
    } 
네트워크 매니저 클래스 ( here에서 "촬영"된)입니다

:

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!! 
    } 
} 

그리고 난 오의 ViewModel 내 LiveData를 얻을 :

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) 
    } 

} 

문제입니다. 위와 같은 방법으로 이벤트 목록을 얻고 있습니다 (이 이벤트는 이미 데이터베이스에 있음). 작동하지 않습니다. 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>