【问题标题】:Android MVVM/Repository how to force LiveData to update from repository?Android MVVM/Repository 如何强制 LiveData 从存储库更新?
【发布时间】:2020-04-24 10:21:57
【问题描述】:

这是我的问题:

我使用过这样的 MVVM/Repository 设计模式:

Activity -(Observes)-> ViewModel 的 LiveData -> Repository -> WebService API (GET Resource)

我有另一个要求 UPDATING Resource 到 WebService。

问题:

更改服务器上的资源后。我如何使 Resource livedata 用新的服务器数据更新自己

我想强制它再次从服务器获取数据,因为其他一些数据可能已被更改。 而且我不想使用本地数据库(房间)并更改它,因为我的服务器数据可能会更改。他们每次都需要获取。

我想到的唯一解决方案是为其创建一个 Livedata Source(作为 dataVersion)。 并在每次更新后增加它(伪代码):

dataVersion = new MutableLiveData();
dataVersion.setValue(0);
// my repository get method hasnt anything to do with the dataVersion.
myData = Transformation.switchmap(dataVersion, versionNum -> { WebServiceRepo.getList() });

以及如何在 ViewModel 中更新 dataVersion。

【问题讨论】:

  • 你为什么这么反对本地数据库?您唯一需要做的就是在每次服务器数据更改时更新它。据我了解,您想要并且知道如何在数据更改(云消息或其他内容)时将信号从服务器发送到您的应用程序。收到此消息后,您可以调用 WebServiceAPI,更新本地数据库,然后您的 ViewModel 可以在 LiveData 帮助下毫无困难地获取实际数据(当然是来自本地数据库的数据)。作为奖励,您的应用可以在没有互联网的情况下运行。
  • 我的用例是一个购物车,大部分商品都有减价和折扣,并且在良好的存在公告时会有很多客户,所以每个用户的购物车实体数据已经保存了服务器中的一个短时间缓存服务器。并且应用程序购物车应在每次重新加载时获取数据,以查看商品是否已从购物车中撤消。 (客户在他们的购物车商品消失之前只有 5 分钟的时间购买商品)。因此,我不会将这些数据保存在本地数据库中。
  • 但我使用缓存破坏机制和版本控制每个更新的列表。

标签: java android mvvm repository-pattern android-livedata


【解决方案1】:

您可以扩展 MutableLiveData 以提供手动获取功能。

public class RefreshLiveData<T> extends MutableLiveData<T> {
    public interface RefreshAction<T> {
        private interface Callback<T> {
             void onDataLoaded(T t);
        }

        void loadData(Callback<T> callback);
    }

    private final RefreshAction<T> refreshAction;
    private final Callback<T> callback = new RefreshAction.Callback<T>() {
          @Override
          public void onDataLoaded(T t) {
               postValue(t);
          }
    };

    public RefreshLiveData(RefreshAction<T> refreshAction) {
        this.refreshAction = refreshAction;
    }

    public final void refresh() {
        refreshAction.loadData(callback);
    }
}

那你就可以了

public class YourViewModel extends ViewModel {
    private RefreshLiveData<List<Project>> refreshLiveData;

    private final GithubRepository githubRepository;
    private final SavedStateHandle savedStateHandle;

    public YourViewModel(GithubRepository githubRepository, SavedStateHandle savedStateHandle) {
         this.githubRepository = githubRepository;
         this.savedStateHandle = savedStateHandle;

         refreshLiveData = Transformations.switchMap(savedStateHandle.getLiveData("userId", ""), (userId) -> {
             githubRepository.getProjectList(userId);
         });
    }

    public void refreshData() {
        refreshLiveData.refresh();
    }

    public LiveData<List<Project>> getProjects() {
        return refreshLiveData;
    }
}

然后仓库可以做:

public RefreshLiveData<List<Project>> getProjectList(String userId) {
    final RefreshLiveData<List<Project>> liveData = new RefreshLiveData<>((callback) -> {
         githubService.getProjectList(userId).enqueue(new Callback<List<Project>>() {
            @Override
            public void onResponse(Call<List<Project>> call, Response<List<Project>> response) {
                callback.onDataLoaded(response.body());
            }

            @Override
            public void onFailure(Call<List<Project>> call, Throwable t) {

            }
         });
    });

    return liveData;
}

【讨论】:

    猜你喜欢
    • 2019-03-02
    • 2020-09-17
    • 2020-05-17
    • 2020-05-09
    • 2020-03-16
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多