Retrofit CREATE请求后不更新ViewModel

时间:2019-01-12 14:32:41

标签: android android-recyclerview retrofit2 android-livedata

我正在使用Retrofit客户端在一个简单的Android项目中执行HTTP请求。当我发送一个CREATE请求时,该项目已在远程SQLite数据库中成功创建,但是ViewModel仍然包含旧列表。当我重新启动我的应用程序,然后再次从服务器获取所有项目时,将显示该项目。

我正在遵循Android-应用架构指南,并且在Repository和ViewModel中都使用LiveData对象。

“我的片段”向ViewModel中的LiveData对象添加了一个Observer:

mViewModel.getAllItems().observe(getActivity(), new Observer<List<Item>>() {
            @Override
            public void onChanged(@Nullable final List<Item> items) {
                // Update the cached copy of the words in the adapter.
                mAdapter.setItems(items);
                mAdapter.notifyDataSetChanged();
            }
        });

在我发送一个CREATE请求后,会触发onChange()函数,但是项目列表没有改变。

改造版本:

// Retrofit
implementation('com.squareup.retrofit2:retrofit:2.5.0') {
    exclude module: 'okhttp'
}
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
implementation 'com.squareup.okhttp3:okhttp:3.6.0'
implementation "com.squareup.okhttp3:logging-interceptor:3.6.0"

编辑

相关代码:

ItemViewModel.java

public class ItemViewModel extends AndroidViewModel {

    private ItemRepository mItemRepository;
    private LiveData<List<Item>> items;

    public ItemViewModel(Application application) {
        super(application);
        this.mItemRepository = new ItemRepository();
    }

    public LiveData<List<Item>> getAllItems() {
        if (this.items == null) {
            this.items = mItemRepository.getAllItems();
        }
        return this.items;
    }

    public void createItem(Item item) {
        this.mItemRepository.createItem(item);
    }

}

ItemRepository.java

public class ItemRepository {

    private WebService mWebservice;
    private MutableLiveData<List<Item>> mAllItems = new MutableLiveData<>();

    public ItemRepository() {
        this.mWebservice = WebClient.getClient().create(WebService.class);
    }

    public LiveData<List<Item>> getAllItems() {
        final MutableLiveData<List<Item>> data = new MutableLiveData<>();
        this.mWebservice.getAllItems().enqueue(new Callback<GetAllItemsResponse>() {
            @Override
            public void onResponse(Call<GetAllItemsResponse> call, Response<GetAllItemsResponse> response) {
                data.setValue(response.body().items);
            }
            @Override
            public void onFailure(Call<GetAllItemsResponse> call, Throwable t) {
                System.out.println(t);
            }
        });
        return data;
    }

    public void insertItem(Item item) {
        mWebservice.createItem(item);
    }

}

2 个答案:

答案 0 :(得分:0)

您实际上需要说“您想获取数据”时才需要获取数据。因此,您可以制作一个LiveData,在其中可以获取新数据。

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<Item>> items;

    private final ItemRepository itemRepository;

    public YourViewModel(ItemRepository itemRepository) {
         this.itemRepository = itemRepository;
         items = itemRepository.getAllItems();
    }

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

    public LiveData<List<Item>> getItems() {
        return items;
    }
}

然后存储库可以执行以下操作:

public RefreshLiveData<List<Item>> getAllItems() {
    final RefreshLiveData<List<Item>> liveData = new RefreshLiveData<>((callback) -> {
         mWebservice.getAllItems().enqueue(new Callback<List<Item>>() {
            @Override
            public void onResponse(Call<List<Item>> call, Response<List<Item>> response) {
                callback.onDataLoaded(response.body());
            }

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

            }
         });
    });

    return liveData;
}

答案 1 :(得分:-1)

public class ItemViewModel extends AndroidViewModel {

    private ItemRepository mItemRepository;
    private LiveData<List<Item>> items;

    public ItemViewModel(Application application) {
        super(application);
        this.mItemRepository = new ItemRepository();
    }

    public LiveData<List<Item>> getAllItems() {
//      if (this.items == null) {
            this.items = mItemRepository.getAllItems();
//      }
        return this.items;
    }

    public void createItem(Item item) {
        this.mItemRepository.createItem(item);
    }

}

请尝试删除此条件