首页 > 解决方案 > 合并多个 LiveData 源?

问题描述

为了更容易想象我的问题,我画了以下内容: 在此处输入图像描述

我正在使用 RoomDatabase、Repository、Viewmodel 和 Livedata。区域与网关具有 1 对 n 的关系,网关与项目具有 1 对 n 的关系。我创建了一个 AreaWithGateways 实体和一个 GatewayWithItems 实体。

项目可以从一个网关移动到另一个,这就是为什么我使用 Livedata 观察它们以跟踪它们所在的网关。我现在的问题是我发现自己还需要跟踪哪些项目在哪些区域和我不知道该怎么做。

我曾想过将每个网关的 LiveData 合并在一起并观察使用 MediatorLiveData 但我并不真正了解如何使用它。或者也许可以创建一个实体 AreaWithGatewayswithItems?

任何见解将不胜感激

编辑:我正在添加一些代码以使问题更清晰

这是区域实体

@Entity(tableName = "area_table")
public class Area {

    @PrimaryKey(autoGenerate = false)
    private int areaId;

    private String areaName;
    private float wertX;
    private float wertY;
    private Boolean isDrawn;


    public int getAreaId() {
        return areaId;
    }

    public void setAreaId(int areaId) {
        this.areaId = areaId;
    }

    public String getAreaName() {
        return areaName;
    }

    public float getWertX() {
        return wertX;
    }

    public float getWertY() {
        return wertY;
    }

    public Boolean getDrawn() {
        return isDrawn;
    }

    public Area(int areaId, String areaName, float wertX, float wertY, Boolean isDrawn) {
        this.areaId = areaId;
        this.areaName = areaName;
        this.wertX = wertX;
        this.wertY = wertY;
        this.isDrawn = isDrawn;
    }
}

网关实体:

@Entity(tableName = "gateway_table")
public class Gateway {
    
    private float temp;
    private String title;
    private int areaId;


    @PrimaryKey(autoGenerate = false)
    private int gatewayId;

    public int getGatewayId() {
        return gatewayId;
    }

    public void setGatewayId(int gatewayId) {
        this.gatewayId = gatewayId;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public float getTemp() {
        return temp;
    }

    public void setTemp(float temp) {
        this.temp = temp;
    }

    public int getAreaId() {
        return areaId;
    }

    public Gateway(int areaId, int gatewayId, String title) {
        this.title = title;
        this.areaId = areaId;
        this.gatewayId = gatewayId;
    }
}

和“项目”实体:

@Entity(tableName = "cow_table")
public class Cow {

    private int age;
    private String sex;
    private String name;
    private boolean drawn;
    private int gatewayId;
    private String raceId;


    @PrimaryKey(autoGenerate = false)
    private int cowId;

    public int getCowId() {
        return cowId;
    }

    public void setCowId(int cowId) {
        this.cowId = cowId;
    }

    public String getName() {
        return name;
    }


    public boolean isDrawn() {
        return drawn;
    }

    public int getAge() {
        return age;
    }

    public String getSex() {
        return sex;
    }

    public void setDrawn(boolean drawn) {
        this.drawn = drawn;
    }

    public int getGatewayId() {
        return gatewayId;
    }

    public String getRaceId() {
        return raceId;
    }

    public Cow(int age, int cowId, int gatewayId,String name, String raceId, String sex, boolean drawn) {

        this.age = age;
        this.cowId = cowId;
        this.sex= sex;
        this.name = name;
        this.drawn = drawn;
        this.gatewayId = gatewayId;
        this.raceId = raceId;
    }


}

这就是“AreaWithGateways”的关系:

public class AreaWithGateways {

    @Embedded
    private Area area;

    @Relation(parentColumn = "areaId",
    entityColumn = "areaId")
    private List<Gateway> gatewayList;

    public Area getArea() {
        return area;
    }

    public List<Gateway> getGatewayList() {
        return gatewayList;
    }

    public AreaWithGateways(Area area, List<Gateway> gatewayList) {
        this.area = area;
        this.gatewayList = gatewayList;
    }
}

以及 GatewaysWithCows:

public class GatewayWithCows {

    @Embedded
    private Gateway gateway;

    @Relation(parentColumn = "gatewayId",
            entityColumn = "gatewayId")
    private List<Cow> cowList;

    public Gateway getGateway() {
        return gateway;
    }

    public List<Cow> getCowList() {
        return cowList;
    }

    public GatewayWithCows(Gateway gateway, List<Cow> cowList) {
        this.gateway = gateway;
        this.cowList = cowList;
    }
}

我一直在尝试找到一种将区域中的所有“项目”作为 Livedata 的方法,但仍然无法弄清楚。我觉得我应该以某种方式使用 AreaWithGateways 将 LiveData 项目添加在一起,但我无法通过网关访问这些项目,它必须是相反的方式。

标签: javaandroidrepositoryandroid-roomandroid-livedata

解决方案


或者也许可以创建一个实体 AreaWithGatewayswithItems?

不是实体,因为它们用于通过 POJO 使用 @Embedded 和 @Relation 注释定义表(例如,您的 GatewayWithCows 是 POJO)。

我觉得我应该以某种方式使用 AreaWithGateways 将 LiveData 项目添加在一起,但我无法通过网关访问这些项目,它必须是相反的方式。

您基本上使用分层方法,但 POJO 的,因此您已经GatewayWithCows从 Area 与此相关,按照:-

class AreaWithGatewayWithCows {

    @Embedded
    Area area;
    @Relation(entity = Gateway.class, parentColumn = "areaId",
            entityColumn = "areaId")
    List<GatewayWithCows> gatewayWithCowsList;

}
  • 请注意,我错过了Gateway 之后的s作为类名(因此在下面的查询中)

  • 请注意entity = Gateway.class,由于关系是通过网关而不是通过 GatewayWithCows(不是表),因此需要使用 of 。

Query Dao 可以很简单:-

@Query("SELECT * FROM area_table")
List<AreaWithGatewayWithCows> getAreaWithGatewaysWithCows();
  • 对 LiveData 进行了相应修改。
  • 请注意,如果您在查询中使用 JOINS,则诸如 WHERE 之类的任何子句只会影响区域,而不影响基础网关和奶牛。这与 @Relation 构建的查询无关,每个查询都Area带有与之相关的ALL ;并且每个人都得到与那相关的所有s 。GatewayAreaGatewayCowGateway

推荐阅读