LiveData n'est pas la mise à jour de sa valeur après le premier appel

J'ai été me frappant la tête contre le mur et je ne comprends pas pourquoi ce qui se passe. Je suis en train de travailler avec la nouvelle Architecture de Composants pour Android et je vais avoir des problèmes pour mettre à jour un LiveData avec une Liste d'Objets.
J'ai deux roulettes. Quand j'ai modifier l'option dans le premier, Le second doit avoir son contenu a changé. Mais cette dernière partie n'est pas le cas.
Quelqu'un peut-il m'aider?

State.java

@Entity(tableName = "states")
public class State{

@PrimaryKey(autoGenerate = false)
private int id;

private String name;

@ColumnInfo(name = "countryId")
private String CountryId;

@Ignore
private Object geoCenter, geoLimit;

public State(){

}

public int getId() {
    return id;
}

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

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getCountryId() {
    return CountryId;
}

public void setCountryId(String countryId) {
    CountryId = countryId;
}
}

StateDAO

@Dao
public interface StateDao {

@Query("SELECT * FROM states")
LiveData<List<State>> getAllStates();

@Query("SELECT * FROM states WHERE countryId = :countryID")
LiveData<List<State>> getStatesFromCountry(String countryID);

@Query("SELECT COUNT(*) FROM states")
int getNrStates();

@Query("SELECT COUNT(*) FROM states WHERE countryId = :countryID")
int getNrStatesByCountry(String countryID);

@Insert(onConflict = IGNORE)
void insertAll(List<State> states);

@Delete
void delete(State state);
}

StateRepository

@Singleton
public class StatesRepository {

private final WebServices services;
private final StateDao stateDao;
private final Executor executor;

@Inject
public StatesRepository(Executor executor, StateDao stateDao, WebServices services) {
    this.services = services;
    this.stateDao = stateDao;
    this.executor = executor;
}


public LiveData<List<State>> getStates(String token){
    refreshStates(token);

    return stateDao.getAllStates();
}

public LiveData<List<State>> getStatesFromCountry(String countryID){

    return stateDao.getStatesFromCountry(countryID);
}

private void refreshStates(final String token){

    executor.execute(() -> {

        Log.d("oooooo", stateDao.getNrStates() + "");
        if(stateDao.getNrStates() == 0){

            try {
                Response<List<State>> response = services.getStates("Bearer "+token).execute();

                stateDao.insertAll(response.body());

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    });
}
}

StateViewModel

public class StatesViewModel extends ViewModel {

private LiveData<List<State>> states;
private StatesRepository repo;

@Inject
public StatesViewModel(StatesRepository repository){

    this.repo = repository;
}

public void init(String token){

    states = repo.getStates(token);
}

public void getStatesFromCountry(String countryID){

    states = repo.getStatesFromCountry(countryID);

}

public LiveData<List<State>> getStates(){

    return this.states;
}

}

Fragment

public class EditAddressFragment extends LifecycleFragment implements View.OnClickListener, Injectable{
private Spinner country, city, state, zip_code;
private String token;
private List<Country> countries;
private List<City> cities;
private List<State> states;
@Inject ViewModelFactory viewModelFactory;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.addresses_edit_layout, container, false);
city = view.findViewById(R.id.city);
state = view.findViewById(R.id.state);
country = view.findViewById(R.id.country);
...
countries = new ArrayList<>();
cities = new ArrayList<>();
states = new ArrayList<>();
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
CountrySpinnerAdapter adapter = new CountrySpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, countries);
country.setAdapter(adapter);
CitySpinnerAdapter cityAdapter = new CitySpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, cities);
city.setAdapter(cityAdapter);
StateSpinnerAdapter stateAdapter = new StateSpinnerAdapter(getActivity(), android.R.layout.simple_spinner_item, states);
state.setAdapter(stateAdapter);
CountriesViewModel countriesViewModel = ViewModelProviders.of(this, viewModelFactory).get(CountriesViewModel.class);
countriesViewModel.init(token);
countriesViewModel.getCountries().observe(this, adapter::setValues);
CityViewModel cityViewModel = ViewModelProviders.of(this, viewModelFactory).get(CityViewModel.class);
cityViewModel.init(token);
cityViewModel.getCities().observe(this, cityAdapter::setValues);
StatesViewModel statesViewModel = ViewModelProviders.of(this, viewModelFactory).get(StatesViewModel.class);
statesViewModel.init(token);
statesViewModel.getStates().observe(this, states -> { 
Log.d("called", states.toString()); 
stateAdapter.setValues(states); } );
country.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
Country c = (Country) adapterView.getItemAtPosition(i);
Log.d("cd", c.getId());
//states = new ArrayList<State>();
statesViewModel.getStatesFromCountry(c.getId());
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});

....

Adaptateur

public void setValues(List<State> states)
{ 
this.states = states; 
Log.d("s", states.isEmpty()+" "+states.toString()); 
notifyDataSetChanged(); 
}
Il est difficile de voir l'image entière... (j'ai d'abord si vous n'avez pas eu LiveData) mais vous ne. Cependant, je vous conseille de vérifier votre threading / simultanéité, puisque vous êtes à l'aide de l'exécuteur testamentaire de votre repo... L'approche que je voudrais prendre (je pense) c'est que chaque toupie est en observant LiveData (différentes) et le ViewModel ferait en sorte de le mettre à jour lorsque l'INTERFACE utilisateur/Spinner1 changements, de sorte que le LiveData observé par l'INTERFACE utilisateur/Spinner2 changements. Si c'est ce que vous êtes en train de faire de l'atm, il est difficile de voir dans le code.
Je le fais dans le référentiel, car c'est là que j'ai le DAO de l'instance. MON Référentiel est là que je fais les appels à l'API ou de la base de données. Dans ce cas, j'ai seulement besoin d'aller à la bd locale car, auparavant, j'ai récupéré tous les états. De tous mes tests, il peut apparemment obtenir la valeur de la DB, mais le onchange de la méthode de l'observateur n'est pas appelé.
c'est le cas. J'ai deux toupies différentes observation de deux LiveData. J'ai aussi vu quelqu'un parler du problème thread, mais je suis en utilisant le même exemple de la DAO, donc il ne devrait y avoir aucun problème avec ça je pense...
Intéressant de noter que j'utilise tous cette nouvelle la merde avec RXJava2 ainsi... quoique je doute fortement que cela a quelque chose à voir avec quoi que ce soit.
Est votre StatesRepository un singleton? Si vous disposez de deux instances de base de données, des événements, de l'un ne seront pas propagées à l'ensemble des observateurs sur l'autre instance.

OriginalL'auteur joao86 | 2017-08-25