视图模型无法观察到更改

时间:2020-05-11 10:29:26

标签: android android-livedata android-viewmodel android-mvvm

我创建了一个依赖于本地服务器的应用程序,该应用程序获取配置文件图像和有关用户的信息。代码可以正常工作,没有任何问题,但是当我更改本地服务器中的数据(例如配置文件图片)时,更新的配置文件在活动重新启动之前不会反映在应用程序中,但是这不会发生,因为实时数据应在数据库中发生更改后立即反映更改。

下面是实时数据类的代码

 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;
    }

这是我的存储库代码

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;

   }

}

主要活动中的代码以观察变化。...
实际上,我在导航抽屉中显示个人资料图片……就像电报应用

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());
        }
    });
}

代码工作正常,但我希望必须在服务器中进行更改后立即更新数据...
但是当我重新启动活动或关闭活动后再次打开应用程序时,数据会更新...

1 个答案:

答案 0 :(得分:3)

可能是问题所在-您开始在活动中观察一个MutableLiveData实例,然后将其替换为另一个。

在您的ViewModel中:

profileMutableLiveData=repository.getProfile(token);

您覆盖它而不是使用“ postValue”设置新值

在您的存储库中:

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

您制作了另一个LiveData实例

您可以尝试将您的返回值从存储库更改为“配置文件”,并使用“ postValue”将其设置为ViewModel中MutableLiveData的新值

已更新

我们已经仔细阅读了您的问题。我认为上述答案无法满足您的期望(以防Retrofit应该像ROOM一样立即更新LiveData)

所以我的想法:

  1. 您期望使用LiveData + Retrofit太多。仅使用它们并不意味着您将在服务器上获得数据的在线更新。为了实现这一点,您必须更改与服务器交互的机制,而不仅仅是在显示的代码中修复几行。
  2. 有一种LiveData + ROOM机制,可以通过LiveData + Retrofit期望的方式与本地DB(Sqlite)一起使用。但是那里没有魔术。 Room正在使用机制,当数据库表中发生某些更改时,该机制内置于Sqlite中,用于通知(触发)。但是Retrofit在Rest Api上没有实现类似的机制,实际上这不是它的责任。
  3. 要实现您想要的目标,您可以查看以下几种可能性:

    • 要使用某些 Cloud Service API ,该API包含用于在数据更改时通知您的设备的内置机制(例如Firebase)
    • 用于实现您的应用数据与服务器的某种定期同步。同步之后,您将在设备上拥有所有数据,并且根据您放置数据的位置,您可以通过LiveData + Room或FileObserver来观察更改。

    • 为简化您的案例并在活动上单击“刷新”按钮后显式刷新活动中的服务器数据。在这种情况下,您可以执行我在答案的第一个版本中写的步骤。