Не обновляет 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);
    }

}

Попробуйте удалить это, если условие

Другие вопросы по тегам