无法从存储库调用数据源



我想从Datasource检索数据。但事实证明它根本没有被执行。我怎么解决它?这是我的代码

Repository.kt

// all logcat in repository is executed
override fun getDetailGame(id: Int): Flow<Resource<Game>> {
Log.d("Repo", "getDetailGame: called")
return flow {
Log.d("Repo", "getDetailGame: before flow")
remoteDataSource.getDetailGame(id)
Log.d("Repo", "getDetailGame: after flow")
}
}

Datasource.kt

suspend fun getDetailGame(id: Int): Flow<ApiResponse<GameResponse>> =
flow {
try {
// didnt get executed all
Log.d(TAG, "getDetailGame: called")
val response = apiService.getDetailGame(id)
if (response != null) {
emit(ApiResponse.Success(response))
} else {
emit(ApiResponse.Empty)
}
} catch (ex: Exception) {
emit(ApiResponse.Error(ex.message.toString()))
Log.e(TAG, "getDetailGame: ${ex.message} ")
}
}.flowOn(Dispatchers.IO)

编辑:添加其他文件的附加代码

ApiResponse.kt(数据源的响应状态管理)

sealed class ApiResponse<out R> {
data class Success<out T>(val data: T) : ApiResponse<T>()
data class Error(val errorMessage: String) : ApiResponse<Nothing>()
object Empty : ApiResponse<Nothing>()
}

Resource.kt(UI的状态管理,如加载状态等)

sealed class Resource<T>(val data: T? = null, val message: String? = null) {
class Success<T>(data: T) : Resource<T>(data)
class Loading<T>(data: T? = null) : Resource<T>(data)
class Error<T>(message: String, data: T? = null) : Resource<T>(data, message)
}

GameResponse.kt(与游戏相同,但与json的serializedname)

data class GameResponse(
@field:SerializedName("id")
var id: Int,
@field:SerializedName("name")
var title: String,
@field:SerializedName("released")
var released: String? = null,
@field:SerializedName("metacritic")
var metacritic: Int? = null,
@field:SerializedName("metacritic_url")
var metacriticUrl: Int? = null,
@field:SerializedName("background_image")
var bgImage: String? = null,
@field:SerializedName("description")
var description: String? = null,
@field:SerializedName("game_series_count")
var gameSeriesCount: Int? = 0
)

Game.kt(与gamerresponse相同,但它的干净版本)

data class Game(
var id: Int,
var title: String,
var released: String? = null,
var metacritic: Int? = null,
var metacriticUrl: Int? = null,
var bgImage: String? = null,
var description: String? = null,
var gameSeriesCount: Int? = 0
)

流是冷流,这意味着在你收集它们之前它们不会被执行。如果您试图将Flow<ApiResponse>转换为Flow<Resource>,则应该使用map函数。如果您需要更复杂的转换,请使用transform

override fun getDetailGame(id: Int): Flow<Resource<GameResponse>> {
return remoteDataSource.getDetailGame(id).map { response ->
when (response) {
ApiResponse.Empty -> Resource.Loading()
is ApiResponse.Success -> Resource.Success(response.data)
is ApiResponse.Error -> Resource.Error(response.errorMessage)
}
}
}

或者如果您需要在执行转换之前发出一个值:

override fun getDetailGame(id: Int): Flow<Resource<GameResponse>> = flow {
emit(Resource.Loading())
emitAll(
remoteDataSource.getDetailGame(id).map { response ->
when (response) {
is ApiResponse.Success -> Resource.Success(response.data)
is ApiResponse.Error -> Resource.Error(response.errorMessage)
ApiResponse.Empty -> Resource.Error("")
}
}
)
}

最新更新