当前位置: 首页 > 知识库问答 >
问题:

LiveData在数据更改时不更新

方增
2023-03-14
UserViewModel userViewModel = ViewModelProviders.of(this).get(UserViewModel.class);
userViewModel.getUser().observe(this, new Observer<User>() {
    @Override
    public void onChanged(User user) {
        //Set UI
    }
});

UserViewModel:

public class UserViewModel extends AndroidViewModel {
    private LiveData<User> user;

    public UserViewModel(Application application) {
        super(application);
        user = UserRepository.getInstance().fetchUser();
    }

    public LiveData<User> getUser() {
        return user;
    }    
}

用户存储库:

public class UserRepository {    
    private ApiService apiService;
    private static UserRepository userRepository;

    private UserRepository() {
        apiService = RestClient.getClient().create(ApiService.class);
    }

    public synchronized static UserRepository getInstance() {
        if (userRepository == null) userRepository = new UserRepository();
        return userRepository;
    }

    public LiveData<User> fetchUser() {
        final MutableLiveData<User> data = new MutableLiveData<>();
        Call<User> call = apiService.getUser();
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(@NonNull Call<User> call, @NonNull Response<User> response) {
                if (response.body() != null) {
                    data.postValue(response.body());
                }
            }

            @Override
            public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) {
                data.postValue(null);
                t.printStackTrace();
            }
        });
        return data;
    }
}

共有1个答案

弘志勇
2023-03-14

问题是每次调用fetchUser时都会创建一个新的LiveData<>

这意味着您的第一个将永远不会收到更新。

请看看这些...

public class UserRepository {    
    private ApiService apiService;
    private static UserRepository userRepository;

    private UserRepository() {
        apiService = RestClient.getClient().create(ApiService.class);
    }

    public synchronized static UserRepository getInstance() {
        if (userRepository == null) userRepository = new UserRepository();
        return userRepository;
    }

    // Your example code
    public LiveData<User> fetchUser() {
        // Your problem lies here. Every time you fetch user data, you create a new LiveData.
        // Instead, fetch user should update the data on a pre-existing LiveData.
        final MutableLiveData<User> data = new MutableLiveData<>();
        Call<User> call = apiService.getUser();
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(@NonNull Call<User> call, @NonNull Response<User> response) {
                if (response.body() != null) {
                    data.postValue(response.body());
                }
            }

            @Override
            public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) {
                data.postValue(null);
                t.printStackTrace();
            }
        });
        return data;
    }

    // My alterations below:
    private MutableLiveData<User> userLiveData = new MutableLiveData<>();

    public LiveData<User> getUser() {
        return userLiveData;
    }

    public LiveData<User> fetchUser2() {
        Call<User> call = apiService.getUser();
        call.enqueue(new Callback<User>() {
            @Override
            public void onResponse(@NonNull Call<User> call, @NonNull Response<User> response) {
                if (response.body() != null) {
                    userLiveData.postValue(response.body());
                }
                // TODO: Consider a fallback response to the LiveData here, in the case that bad data is returned. Perhaps null?
            }

            @Override
            public void onFailure(@NonNull Call<User> call, @NonNull Throwable t) {
                userLiveData.postValue(null);
                t.printStackTrace();
            }
        });
        return userLiveData;
    }
}
user = UserRepository.getInstance().getUser();
UserRepository.getInstance().fetchUser2();
private UserRepository() {
    apiService = RestClient.getClient().create(ApiService.class);
    fetchUser2();
}
userViewModel.getUser().observe(getViewLifecycleOwner(), new Observer<User>() {
    @Override
    public void onChanged(User user) {
        //Set UI
    }
});
 类似资料:
  • 我目前正在重构遗留代码,以使用Android架构组件,并在一种存储库模式中设置一个房间数据库和截取请求。因此,表示层/域层要求存储库获取LiveData对象进行观察,或告诉他与服务器同步,然后删除旧的db条目,并从服务器中重新提取所有当前条目。 我已经写了同步部分的测试,所以我确信,对象被正确地获取并插入到数据库中。但是当写一个测试来观察db表的条目时(并测试对象是否被正确保存,以及在将它们放入d

  • 我正在使用Android MVVM架构和LiveData。我有一个这样的物体 我的视图模型是这样的 如何确保用户对象中的某个字段发生更改时,观察员收到通知?顺便说一句,重要的是要将这些数据保存在单独的对象中,而不是在ViewModel中使用字符串等主要值。

  • 这个问题可能已经得到了回答,我读过很多类似的,但对我不起作用。因此,我的具有扩展的自定义表模型。我的数据是和列名。那么,当我的数据发生更改时,如何更新表呢?我一直在使用,它正在工作,但它将我的自定义单元格呈现器重置为默认值。谢了。

  • 我试图在下面的代码中找出,为什么当我用新数据填充数据库时,Room的LiveData observable没有给我新的班次。 这是放在我的activity的onCreate方法上的: 这是populateAdapter方法: 我还有以下填充数据库的代码(我使用RxJava在IO线程上完成这项工作,因为Room需要在主线程之外调用它的代码): 当我开始观察ShiftsViewModel之后调用per

  • RecycerView只显示创建时ArrayList(适配器的数据)中的项。我所有添加更多行的尝试似乎都奏效了,但列表仍然是初始数据。它不是重复的,因为我尝试了谷歌上找到的所有建议。我已经做了什么: Adapter.NotifyDataSetChanged(); Adapter.NotifyItemChanged(5); recyleList.invalidate(); recyclelist.s

  • 问题内容: 我有一个ng-repeat,它在更改正在使用的数组中的数据时不会更新。我已经研究了一段时间,但似乎没有任何效果。最初,当页面加载时,ng- repeat显示数据集的第一页,在获取新数据(下一页)并使用该数据设置该数组时,ng- repeat不会注意到更改,并且永远不会填充更新的数组。如果有人可以在正确的方向上指导我,将不胜感激。 }]); 问题答案: 尝试将tbody包装在div中,但