【问题标题】:Android Room: Handling Relations with LiveDataAndroid Room:处理与 LiveData 的关系
【发布时间】:2017-12-20 14:18:00
【问题描述】:

所以我有两个模型(表),WordGroupsWords,它们之间的关系是一对多的。 所以我的模型和Dao 看起来像:

@Entity
public class WordGroup {

    @PrimaryKey
    private int id;

    @Ignore
    private List<Word> words;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public List<Word> getWords() {
        return words;
    }

    public void setWords(List<Word> words) {
        this.words = words;
    }
}

@Entity
public class Word {

    @PrimaryKey
    private int id;

    @ForeignKey(entity = WordGroup.class, parentColumns = "id", childColumns = "wordGroupId")
    private int wordGroupId;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getWordGroupId() {
        return wordGroupId;
    }

    public void setWordGroupId(int wordGroupId) {
        this.wordGroupId = wordGroupId;
    }
}

@Dao
public interface Dao {

    @Query("select * from WordGroup where id = :id")
    LiveData<WordGroup> selectWordGroupById(int id);

    @Query("select * from WordGroup")
    LiveData<List<WordGroup>> selectAllWordGroups();

    @Query("select * from Word where wordGroupId = :wordGroupId")
    LiveData<List<Word>> selectWordsByWordGroupId(int wordGroupId);
}

现在我有一个方法可以选择 WordGroup 并使用 Transformations 设置其 Words:

public LiveData<WordGroup> getWordGroupWithWords(int id) {
    LiveData<WordGroup> wordGroupLiveData = dao.selectWordGroupById(id);

    LiveData<WordGroup> wordGroupWithWordsLiveData = Transformations.switchMap(wordGroupLiveData, inputWordGroup -> {
        LiveData<List<Word>> wordsLiveData = dao.selectWordsByWordGroupId(inputWordGroup.getId());

        LiveData<WordGroup> outputWordGroupsLiveData = Transformations.map(wordsLiveData, inputWords -> {
            inputWordGroup.setWords(inputWords);
            return inputWordGroup;
        });

        return outputWordGroupsLiveData;
    });

    return wordGroupWithWordsLiveData;
}

现在我想编写一个方法来选择所有WordGroups,同时为每个WordGroup 设置它们的Words。方法的签名应该是这样的:

public LiveData<List<WordGroup>> getAllWordGroupsWithWords();

【问题讨论】:

    标签: android android-room android-livedata


    【解决方案1】:

    好吧,我尝试了更多,并在MediatorLiveData 的帮助下想出了这个解决方案:

    public LiveData<List<WordGroup>> getAllWordGroupsWithWords() {
        LiveData<List<WordGroup>> wordGroupsLiveData = dao.selectAllWordGroups();
        LiveData<List<WordGroup>> outputWordGroups = Transformations.switchMap(wordGroupsLiveData, inputWordGroups -> {
            MediatorLiveData<List<WordGroup>> wordGroupsMediatorLiveData = new MediatorLiveData<>();
            for (WordGroup wordGroup : inputWordGroups) {
                wordGroupsMediatorLiveData.addSource(dao.selectWordsByWordGroupId(wordGroup.getId()), words -> {
                    wordGroup.setWords(words);
                    wordGroupsMediatorLiveData.postValue(inputWordGroups);
                });
            }
    
            return wordGroupsMediatorLiveData;
        });
    
        return outputWordGroups;
    }
    

    现在这正是我想要的方式,但存在一些大问题。

    • 首先,如果您在MediatorLiveData 上使用方法setValue,它将多次调用观察者,我可以通过使用postValue 来减少调用观察者的次数

    • 第二次即使只换一个字,也会再次为每个wordGroup调用观察者!

    当然,它不是最优化的解决方案,但它确实有效。我非常愿意接受建议和改进。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多