TL; DR版本
我想拥有一个返回签名为LiveData<User>
的方法,其中User
是一个接口。实现返回一个LiveData<UserEntity>
,其中UserEntity
是扩展User
的具体类。如下所示:
fun getUser(id: String): LiveData<User> {
// for brevity
return LiveData<UserEntity>() // actual code will retrieve data from db
}
编译器抱怨return type not match error
TL;版本
我正在阅读Jetpack guide。他们在其中设计了一个DataRepository
类,可以从DB或WebService检索数据,如下图所示:
他们声称
请注意,每个组件仅取决于其下一级的组件。
这是一个吸引人的设计,实际上我试图在自己的项目中复制它。 但是,我发现WebService
不可避免地依赖于Room
,因为它是方法getUser()
返回LiveData
的{{1}},这是房间实体。
此问题可能不会破坏应用程序,但与“关注点分离”原理的基本设计相矛盾,并且在外观上是丑陋的恕我直言。
我的问题是:有什么解决方法吗?我试图将User
重构为接口,并实现了一个User
类来扩展它。如下所示:
UserEntity
interface User {
val id: String
val name: String
val lastName: String
}
@Entity(tableName="users")
data class UserEntity(
override val id: String
override val name: String
override val lastName: String) : User
请注意,我必须返回@Dao
interface UserDao() {
@Query("SELECT * FROM users where id = :id")
fun getUser(id: String): LiveData<UserEntity> // UserEntity instead of User, because Room doesn't know how to construct an interface
}
的{{1}} int,因为Room不知道如何构造接口。
这是问题所在:以下代码无法编译:
UserEntity
错误表明
User
答案 0 :(得分:1)
上面的代码将不起作用,因为您不能期望函数返回多种数据类型。我建议使用一个User类,将Room和GSON映射合并。
@Entity(tableName="users")
data class Users(
@PrimaryKey // Room annotation
@SerializedName("id") // Gson annotation
val id: String,
@ColumnInfo(name = "name")
@SerializedName("name")
val name: String,
@ColumnInfo(name = "lastName")
@SerializedName("lastName")
val lastName: String,
)
您可以摆脱UserEntity类,并将其用作API和数据库存储库的DTO。