Changes are not observable by viewmodel

Viewed 215

I have created an app which is relied on my local server which fetch profile image and information about user..Code works fine without any problem but when I change my data in the local server (for example profile picture )the updated profile is not reflecting in the application until activity is restarted but this should not be happened because live data should reflect the change immediately as soon as changes occurred in the database.

below is the code of live data class

 private MutableLiveData<Profile> profileMutableLiveData;
 public void init(String token){
        if (profileMutableLiveData!=null){
            return;
        }
        repository=Repository.getInstance();
        profileMutableLiveData=repository.getProfile(token);
    }
public LiveData<Profile> getProfile(){
         return profileMutableLiveData;
    }

here is my Repository code

public class Repository {
   private static Repository instance;


   public static Repository getInstance(){
       if (instance==null){
           instance=new Repository();
       }
       return instance;
   }

   public MutableLiveData<Profile> getProfile(String token){
       MutableLiveData<Profile> data=new MutableLiveData<>();
       RetrofitApi retrofitApi=RetrofitInstance.getInstance();
       Call<Profile> call=retrofitApi.getProfile(token);
       call.enqueue(new Callback<Profile>() {
           @Override
           public void onResponse(Call<Profile> call, Response<Profile> response) {
               Profile profile=response.body();
               if (response.isSuccessful()){
                    data.setValue(profile);
               }
           }

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

           }
       });
       return data;

   }

}

Code in main activity to observe changes....
actually I am showing profile image in navigation drawer ... like telegram app

viewModelClass = new ViewModelProvider(this).get(ViewModelClass.class);
viewModelClass.init(token);
viewModelClass.getProfile().observe(this, new Observer<Profile>() {
    @Override
    public void onChanged(Profile profile) {

        Picasso.get().load("http://192.168.43.216:8000" + profile.getProfile_photo()).into(profileImage);
        
        fName = profile.getFirst_name();
        lName = profile.getLast_name();
        image = profile.getProfile_photo();
        nameView.setText("Hello " + profile.getFirst_name());
        }
    });
}

The code is working fine but I want the data must be updated as soon as changes made in my server...
but data is updated when I restart the activity or opening app again after closing the activity...

1 Answers

May be the problem - is that you begin to observe in your activity one instance of MutableLiveData, and then you replace it with another one.

In your ViewModel:

profileMutableLiveData=repository.getProfile(token);

you override it instead of setting new value with "postValue"

In your Repository:

MutableLiveData<Profile> data=new MutableLiveData<>();

you make another instance of LiveData

You can try to change your return value from a Repository to a "Profile" and set it as a new value of MutableLiveData in your ViewModel with "postValue"

UPDATED

I've read your question more carefully. I think my answer above wouldn't give you what you expect (in case you expect Retrofit should update LiveData instantly like ROOM does)

So my thoughts:

  1. You expect too much using LiveData+Retrofit. Just using them doesn't mean you'll get on-line updates of your data on your server. To achieve that you have to change mechanism of your interaction with your server, not just fix few lines in code you've shown.
  2. There is mechanism LiveData+ROOM that works with local DB (Sqlite) in a way, that you expect from LiveData+Retrofit. But there is no magic there. Room is using mechanic, that built-in in Sqlite for notifying (triggering) when there are some changes in DB tables occur. But Retrofit doesn't implement similar mechanism with Rest Api and actually it's not its responsibility.
  3. To achieve what you want you can look at several possibilities:

    • To use some Cloud Service API, that contains that built-in mechanism for notifying your device when data changes (Firebase, for example)
    • To implement some kind of periodic synchronisation of your app data with server. After this synchronisation you'll have all data on device and depending on where you put your data you could observe changes with LiveData+Room or FileObserver.

    • To simplify your case and refresh your data from the server at activity explicitly after click on Button "Refresh" on your activity. In that case you can implement steps that I wrote at first version of my answer.

Related