从房间返回接口的LiveData?

时间:2019-12-19 15:46:41

标签: android persistence android-room android-livedata android-jetpack

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检索数据,如下图所示: app structure from Jetpack guide 他们声称

  

请注意,每个组件仅取决于其下一级的组件。

这是一个吸引人的设计,实际上我试图在自己的项目中复制它。 但是,我发现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

1 个答案:

答案 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。