Не обновляет ViewModel после запроса Retrofit CREATE
Я использую клиент Retrofit для выполнения HTTP-запросов в простом проекте Android. Когда я отправляю запрос CREATE, элемент успешно создается в удаленной базе данных SQLite, но ViewModel по-прежнему содержит старый список. Когда я перезапускаю свое приложение и снова получаю все элементы с сервера, этот элемент появляется.
Я следую Android-Руководству по архитектуре приложений и использую объекты LiveData как в своем репозитории, так и в ViewModel.
Мой фрагмент добавляет Observer к объекту LiveData в ViewModel:
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();
}
});
Функция onChange() запускается после отправки запроса CREATE, но список элементов не изменился.
Модифицированная версия:
// 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 ответа
Вам просто нужно получить данные, когда вы на самом деле говорите "вы хотите получить данные". Таким образом, вы можете сделать 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;
}
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);
}
}
Попробуйте удалить это, если условие